题目 leetcode 239 有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。
1 2 3 4 5 6 7 8 例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时: [4 3 5] 4 3 3 6 7 4 [3 5 4] 3 3 6 7 4 3 [5 4 3] 3 6 7 4 3 5 [4 3 3] 6 7 4 3 5 4 [3 3 6] 7 4 3 5 4 3 [3 6 7] 窗口中最大值为5,窗口中最大值为5 ,窗口中最大值为5,窗口中最大值为4,窗口中最大值为6,窗口中最大值为7
如果数组长度为n,窗口大小为w
,则一共产生n-w+1
个窗口的最大值。
请实现一个函数。输入:整型数组arr
,窗口大小为w。 输出:一个长度为n-w+1
的数组res,res[i]
表示每一种窗口状态下的以本题为例,结果应该为[5,5,5,4,6,7]
滑动窗口 滑动窗口就是一个动态的窗口,这个窗口可以是固定长度,也可以是可变长度。使用双端队列实现滑动窗口这种数据结构,滑动窗口从头部到尾部由大到小 。
双端队列维持的是什么信息?如果目前的R不在扩大,让L依次移动1个位置,得到每个位置时窗口的最大值 。
什么情况可以用滑动窗口来解决实际问题呢?
一般给出的数据结构是数组或者字符串
求取某个子串或者子序列最长最短等最值问题或者求某个目标值时
该问题本身可以通过暴力求解
时间复杂度 :窗口划过数字时,每个位置的数最多进窗口一次,最多出窗口一次。O(n)
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class MaxSlidingWindow { public int [] maxSlidingWindow(int [] nums, int k) { LinkedList<Integer> deque = new LinkedList<>(); List<Integer> result = new ArrayList<>(); int L = 0 ; int R = 0 ; for (int i = 0 ; i < nums.length; i++) { while (deque.size() > 0 && nums[deque.getLast()] < nums[i]) { deque.removeLast(); } deque.add(i); if (R - L + 1 == k) { result.add(nums[deque.getFirst()]); if (nums[deque.getFirst()] == nums[L]) { deque.removeFirst(); } L++; } R++; } return result.stream().mapToInt(Integer::intValue).toArray(); } public static void main (String[] args) { MaxSlidingWindow maxSlidingWindow = new MaxSlidingWindow(); int [] nums = {1 }; System.out.println(Arrays.toString(maxSlidingWindow.maxSlidingWindow(nums, 1 ))); } }