资讯专栏INFORMATION COLUMN

数据结构与算法随笔之优先队列-求滑动窗口最大值(三)

Joyven / 2642人阅读

摘要:你只可以看到在滑动窗口内的数字。滑动窗口每次只向右移动一位。返回滑动窗口最大值。

这篇文章我们来看一道题目求滑动窗口最大值问题(在leetcode上的地址:滑动窗口最大值)

题目描述

给定一个长度为N的数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。返回滑动窗口最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解决方案

一、使用最大堆来实现

首先定义一个大小为K的最大堆,把窗口里面的数据入堆,这样堆顶的数据就是最大值,当窗口向右移动的时候,我们还需要做的一件事情就是把不在窗口的数据移出堆,把进入窗口的数据放入堆,此时堆也会做相应调整,维持最大值在堆顶。代码如下:

public class SlidingWindow {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums == null || nums.length == 0 || k < 1 || k > nums.length) {
            return null;
        }
        if(k == 1) {
            return nums;
        }
        int[] result = new int[nums.length - k + 1];
        int j = 0;
        //用优先队列构建最大堆
        PriorityQueue queue = new PriorityQueue<>(k, new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if(o1.compareTo(o2) == 0) {
                    return 0;
                }else if(o1.compareTo(o2) > 0) {
                    return -1;
                }else {
                    return 1;
                }
            }
        });
        for(int i=0;i 0) {
                queue.remove(nums[i-k]);
            }
            //把移进窗口的数据加入最大堆,最大值一定会在堆顶
            queue.add(nums[i]);
            if(i-k+1 < 0) {
                continue;
            }
            result[j++] = queue.peek();
        }
        return result;
    }
}

复杂度分析

时间复杂度:O(nlogk)

二、使用双端队列来实现

定义一个大小为K的双端队列,把窗口里的数据放入队列,每次入队的时候进行判断,队列里面小于入队数据时,需要出队,一定保持最大值在队列的最左端,代码实现如下:

public class SlidingWindow {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums == null || nums.length == 0 || k < 1 || k > nums.length) {
            return null;
        }
        if(k == 1) {
            return nums;
        }
        int[] result = new int[nums.length - k + 1];
        int m = 0;
        ArrayDeque queue = new ArrayDeque<>(k);
        for(int i=0;i

复杂度分析

时间复杂度:O(n)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71820.html

相关文章

  • LeetCode JavaScript 解答第239题 —— 滑动窗口大值(Sliding W

    摘要:你只可以看到在滑动窗口内的数字。滑动窗口每次只向右移动一位。返回滑动窗口最大值。算法思路暴力破解法用两个指针,分别指向窗口的起始位置和终止位置,然后遍历窗口中的数据,求出最大值向前移动两个指针,然后操作,直到遍历数据完成位置。 Time:2019/4/16Title: Sliding Window MaximumDifficulty: DifficultyAuthor: 小鹿 题目...

    spacewander 评论0 收藏0
  • 如何使用数组实现滑动窗口

    摘要:理解数组实现的滑动窗口,看下边这个图就可以了。第秒,开始计数,此时数组内开始存入计数周期,保存在数组第个位置,表示这是当前滑动窗口内的第个计数周期。在FireflySoft.RateLimit之前的版本中,进程内滑动窗口的实现是基于MemoryCache做的,虽然能够正确的实现滑动窗口的算法逻辑,但是性能比较差,其吞吐量只有其它算法的1/4。性能为何如此之差呢?滑动窗口的原理我们先来看下滑动...

    不知名网友 评论0 收藏0

发表评论

0条评论

Joyven

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<