leetcode经典例题——滑动窗口最大值
题目描述:
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算法文章中~~