LeetCode 239.滑动窗口最大值

这道题的题目比较简单,就是在数组中滑动窗口,并找出每次滑动之后窗口中的最大值输出,题目如下所示:
LeetCode 239.滑动窗口最大值_第1张图片
在上一篇博文数据流中的第K大元素中提到了优先队列,我们可以尝试用优先队列来解答这个问题,首先移动窗口的时候,我们需要把窗口最左边的元素剔除掉,然后将新进入的元素加入到优先队列中,然后再在大顶堆中整理元素位置,代码如下:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int numLen = nums.length;
        if(nums == null || numLen maxHeap = new PriorityQueue((a,b)->nums[b]-nums[a]);
        
        for(int i=0;i

这个时候的时间复杂度为: O ( N ⋅ log ⁡ K ) O(N \cdot \log K) O(NlogK),我们可以用双向队列来求解此问题更加简化了时间复杂度,整个过程如下图所示:
LeetCode 239.滑动窗口最大值_第2张图片
假设有一个数组 [ 1 , 3 , − 1 , − 3 , 5 , 3 , 6 , 7 ] [1,3, - 1, - 3,5,3,6,7] [1,3,1,3,5,3,6,7] K = 3 K=3 K=3,我们用双端队列,每一轮进行移动窗口、维护和输出的动作,每一轮使最大的数在窗口的最左端,如果窗口中左边的元素要小于右边的元素,那么就把左边的元素进行清除维护,最终就能输出结果,图中红色的部分表示窗口的位置。代码如下:

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if not nums:
            return []
        window, res = [], []
        for i, x in enumerate(nums):
            if i >= k and window[0] <= i - k:
                window.pop(0)
            while window and nums[window[-1]] <= x:
                window.pop()
            window.append(i)
            if i >= k-1:
                res.append(nums[window[0]])
        return res

这个时候整个算法的时间复杂度就为: O ( N ) O(N) O(N),比上面用优先队列的方法时间复杂度要低很多。这就是滑动窗口中用优先队列和双向队列的解法,希望对大家有所帮助,谢谢。

你可能感兴趣的:(LeetCode)