
我的思路
这个题目我的第一思路就是暴力解法,因为这个题目的基础逻辑很简单,就是不断的去求每一个区间的最大值即可。
那么我们可以直接创建left和right数组,然后遍历这个数组中的每一个滑动窗口,然后得出其中的最大值,并将其填入结果中即可。
public int[] maxSlidingWindow(int[] nums, int k) {
int left = 0,right = 0;
int[] ans = new int[nums.length-k+1];
for( ; left<nums.length-k+1;left++){
int max = nums[left];
for(right = left;right<left+k;right++){
max = Math.max(max,nums[right]);
}
ans[left] = max;
}
return ans;
}
这种暴力解法只能够通过41/51个测试用例,所以我们要想办法降低时间消耗
我的最初想法是利用这个Treeset集合进行快速排序,但是这个有个问题就是如果这个数组中有重复的最大值,它不仅会将这个窗口中的第一个元素删除掉,也会将这个数组的其它部分删除了。
public static int[] leecode239(int[] nums, int k) {
int[] ans = new int[nums.length-k+1];
TreeSet<Integer> set = new TreeSet<>();
for(int i = 0;i<k;i++){
set.add(nums[i]);
}
ans[0] = set.last();
for(int i = k;i<nums.length;i++){
set.remove(nums[i-k]);
set.add(nums[i]);
ans[i-k+1]=set.last();
}
return ans;
}
灵神思路
灵神是利用了双端队列来实现的这个,他并没有存放这个窗口中的所有元素,而是观察出来这个窗口的最大值规律
灵神利用了滑动窗口和双端队列,利用双端队列记录本轮中最大值的位置,但是他不仅仅记录了这个最大值的位置,还记录了可能作为下一轮窗口最大值的位置(只要这个元素大于左边的元素,就有可能作为后续的最大值,如果这个元素小于左边的元素,那么就不会作为后续的最大值)
滑动窗口三步走,进,出,记录答案
-
元素进入窗口
-
先判断窗口中是否为空的,如果不为空,判断这个元素与队列中的最近添加的元素的大小关系,如果这个元素比较大 ,那么说明,它可能是后续窗口的最大值,队列中的最后一个元素就不可能是最大值了
- 比如说4,1,2,5,6对于这个数组来说,当1后面是2的时候,那么这个窗口中1就不可能是最大值,1后面的窗口也不能是1为最大值,可能是2为最大值
-
元素进入窗口
-
-
元素出窗口
- 获取元素的左端点。
- 判断这个队列中是否存了窗口以外的下标,如果存了,将其移出去,如果没有就不做修改
-
更新答案,以数组为:4,1,6,7,4。k=3来说
- 第一个窗口,下标为0,1,2但是当i=3时,发现
nums[deque.getLast()]<=nums[i],此时就会把下标1删除,删除之后发现还是nums[deque.getLast()]<=nums[i],继续删除,最后就是保留了这个窗口中最大值的下标2 - 第二个窗口中,下标为1,2,3。一样会把这个6的下摆哦删除,保留7的下标
- 以此类推
- 第一个窗口,下标为0,1,2但是当i=3时,发现
public int[] maxSlidingWindow(int[] nums, int k) {
int[] ans = new int[nums.length-k+1];
Deque<Integer> deque = new ArrayDeque<>();
for(int i = 0;i<nums.length;i++){
//进入窗口
//窗口中记录滑动窗口中的较大元素,比如说4,1,2,对于这个数组来说,当1后面是2的时候,那么这个窗口中1就不可能是最大值,1后面的窗口也不能是1为最大值,可能是2为最大值
while (!deque.isEmpty()&&nums[deque.getLast()]<=nums[i]){
deque.removeLast();
}
deque.addLast(i);
//出窗口
int left = i-k+1;//窗口的左端点
if(deque.getFirst()<left){
deque.removeFirst();
}
//更新答案,刚开始只保存,但是不更新,遇到第一个窗口之后才更新
if(left >= 0){
ans[left]=nums[deque.getFirst()];
}
}
return ans;
}
1万+



被折叠的 条评论
为什么被折叠?



