剑指 Offer 59 - I. 滑动窗口的最大值
题目描述
给定一个数组nums和滑动窗口的大小k,请找出所有滑动窗口里的最大值。
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 输出: [3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7🔗题目链接:https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof
思路
单调队列,维护一个队列使其队头元素为当前滑动窗口的最大值,具体操作如下:
- 将进入窗口的新元素与队尾元素进行比较,新元素大于队尾元素就将队尾元素出队,否则就入队新元素,如窗口元素[1,3,-1],则对应的队列元素为[3,,-1];
-
每次移动窗口时先判断移出窗口的元素,即窗口最左端的元素是否为队头元素,是就将其出队,再将新的元素入队到合适的位置,接着取队头元素存入结果数组,作为当前窗口的最大值。
代码实现
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0 || k == 0){
return new int[0];
}
int[] res = new int[nums.length - k + 1];
Deque<Integer> deque = new LinkedList<>();
//维护队头元素为当前队列及滑动窗口中的最大值
for(int i = 0; i < k; i++){ //先形成规定的滑动窗口
while(!deque.isEmpty() && deque.peekLast() < nums[i]){
//若当前元素大于队尾元素,就将队尾元素出队
deque.removeLast();
}
deque.addLast(nums[i]); //将当前元素进行入队
}
res[0] = deque.peekFirst();
for(int i = k; i < nums.length; i++){
if(deque.peekFirst() == nums[i - k]){
//若队头元素等于窗口最左端的值,即原窗口的最大值要被移出了,
//则需要先将其出队,因为它已经不是本次窗口的最大值了
deque.removeFirst();
}
//移除队列中小于窗口新元素的值,将新元素入队
while(!deque.isEmpty() && deque.peekLast() < nums[i]){
deque.removeLast();
}
deque.addLast(nums[i]);
//取当前队列的队头元素加入结果数组
res[i - k + 1] = deque.peekFirst();
}
return res;
}
}
剑指 Offer 59 - II. 队列的最大值
题目描述
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
🔗题目链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof
若队列为空,pop_front 和 max_value 需要返回 -1
🔗题目链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof
思路
单调队列,通过一个辅助队列维护队列的最大值,具体操作与上题类似。
代码实现
class MaxQueue {
Deque<Integer> deque;
Deque<Integer> subDeque; //辅助队列
public MaxQueue() {
deque = new LinkedList<>();
subDeque = new LinkedList<>();
}
public int max_value() {
if(deque.isEmpty()){
return -1;
}
return subDeque.peekFirst(); //返回队头元素
}
public void push_back(int value) {
deque.offer(value);
//将辅助队列中队尾元素与value比较,小于的移出队列,直到队列为空或遇到大于等于value的元素
while(!subDeque.isEmpty() && subDeque.peekLast() < value){
subDeque.removeLast();
}
subDeque.offer(value); //接着将该值入队
}
public int pop_front() {
if(deque.isEmpty()){
return -1;
}
int value = deque.poll();
if(value == subDeque.peekFirst()){ //当出队元素与辅助队列队头元素相等时才出队
subDeque.poll();
}
return value;
}
}
/**
* Your MaxQueue object will be instantiated and called as such:
* MaxQueue obj = new MaxQueue();
* int param_1 = obj.max_value();
* obj.push_back(value);
* int param_3 = obj.pop_front();
*/

京公网安备 11010502036488号