标签:deque 窗口 nums int 最大值 算法 滑动
经典算法思想之滑动窗口
滑动窗口
https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
剑指 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
分析:
数组的长度为n 窗口的大小为k 可形成的窗口个数 n-k+1
通过队列来记录最大值
窗口未形成的阶段
遍历数组,同时更新队列
窗口已形成的阶段
每次窗口移动,都是在头部移除元素,尾部增加元素
在窗口变化过程中 记录其最大值的变化 (让最大值一直出现在第一位)
让队列中已存在的元素 和新添加的元素比较 如果已存在的更小 那么覆盖
如果已存在的更大 新添加的元素是候选 缀到队列之后
滑动窗口的位置 最大值
[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
窗口 max队列
[1 3 -1] [1] -> [3] -> [3,-1]
[3 -1 -3] [3,-1,-3]
[-1 -3 5] [-1,-3] -> [5]
[-3 5 3] [5,3]
[5 3 6] [6]
[3 6 7] [7]
public static int[] maxSlidingWindow(int[] nums, int k) {
// 记录每个窗口的最大值 n-k+1为形成的窗口个数
int[] result = new int[nums.length - k + 1];
// 使用队列记录最大值的候选值
Deque<Integer> deque = new ArrayDeque<>();
// 窗口未形成的阶段
for (int i = 0; i < k; i++) {
print(deque);
// 每次都取 队尾元素和新元素 比较 如果队尾更小 删除
while (!deque.isEmpty() && deque.peekLast() < nums[i]){
deque.pollLast();
}
deque.offerLast(nums[i]);
}
// 此时第一个窗口形成 deque的队头元素就是第一个窗口的最大值
result[0] = deque.peekFirst();
print(deque);
// 窗口已形成的阶段
for (int i = k; i < nums.length; i++) {
System.out.println("-----第" + (i-k+1) + "次滑动");
// 删了元素 nums[i-k] 添了元素 nums[i]
if(nums[i-k] == deque.peekFirst()){
// 如果删的是最大值 同时从deque移除
deque.pollFirst();
}
// 新增
while (!deque.isEmpty() && deque.peekLast() < nums[i]){
deque.pollLast();
}
deque.offerLast(nums[i]);
result[i-k+1] = deque.peekFirst();
print(deque);
}
return result;
}
public static void print(Deque<Integer> deque){
for (Integer integer : deque) {
System.out.print(integer + " ");
}
System.out.println();
}
标签:deque,窗口,nums,int,最大值,算法,滑动 来源: https://blog.csdn.net/m0_51945027/article/details/113792044
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。