题目描述:
1、暴力比较(可能超出时间限制)
思路:题目是要求我们把大小为k的滑动窗口的最大值添加进数组并返回,所以我们首先想的肯定是每移动一次做一次判断:
需要一个方法,能计算滑动窗口内的最大值下标,maxVal()
初始化参数,int i=k(即将进入滑动窗口的数),int maxIndex = maxVal()(滑动窗口最大值的下标),int index = i-k(表示滑动窗口的第一个数,即下一轮滑动要弹出的值)
当nums[i] > nums[index] , maxIndex = i
当nums[i] <= nums[index],有两种情况
当index=maxIndex,重新新计算maxIndex = maxVal();
当index != maxIndex,maxIndex不变
直接进入代码:
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length < 2|| nums == null) return nums;
int[] res = new int[nums.length-k+1];
int maxIndex = maxVal(nums,0,k) ;
res[0] = nums[maxIndex];
for(int i = k;i<nums.length;i++){
int index = i - k;
if (nums[i] >= nums[maxIndex]){
res[index+1] = nums[i];
maxIndex = i;
} else {
if (index == maxIndex){
maxIndex = maxVal(nums,index+1,i+1);
res[index+1] = nums[maxIndex];
}
else res[index+1] = nums[maxIndex];
}
}
return res;
}
private int maxVal(int[] nums ,int begin, int k){
int max = nums[begin];
int index = begin;
for (int i = begin+1; i < k; i++) {
if(max < nums[i]){
max = nums[i];
index = i;
}
}
return index;
}
2、队列实现滑动窗口
思路:既然是滑动窗口,一头要添加元素,一头要弹出元素,我们就可以利用队列来实现
保证queue.peek()也就是队列的第一个值是最大值,这样我们求滑动窗口的最大值,就可以直接返回队列的queue.peek(),那我们怎么可以保证呢?
我们就需要用一个循环,当nums[queue.peekLast()] <= nums[i],弹出队列最后一个元素queue.pollLast,直到队列中的第一个元素queue.peek()才是最大值;
而且而外加入一个判断,如果队列中的第一个元素,也就是滑动窗口第一个元素queue.peek() <= i - k,我们直接滑动一次,弹出第一个元素;
可以看图理解一下例题:
进入代码:
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length < 2|| nums == null) return nums;
int[] res = new int[nums.length-k+1];
LinkedList<Integer> queue = new LinkedList<>();
for (int i = 0; i < nums.length; i++) {
while (!queue.isEmpty() && nums[queue.peekLast()] <= nums[i])
queue.pollLast();
queue.add(i);
if (queue.peek() <= i - k)
queue.poll(); //弹出滑动窗口第一个元素
if (i+1 >= k)
res[i-k+1] = nums[queue.peek()];
}
return res;
}
持续更新leetcode算法文章中~~