hot100:11滑动窗口的最大值

题目链接:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

算法思想:

法一(暴力):

暴力的算法是我刚开始做这个题目使用的方法,通过了测试用例,但是提交的时候超出了时间限制,我就说暴力能通过的话为什么设定成困难,但是这也一种思想,不详细介绍了,代码如下:

public int[] maxSlidingWindow(int[] nums, int k) {
        //定义一个数组用来存储窗口中的最大值
        int[] ret = new int[nums.length-k+1];
        for(int i = 0;i < nums.length - k + 1;i++) {
            int max = getMax(nums,i,i+k-1);
            ret[i] = max;
        }
        return ret;
    }

    public int getMax(int[] nums,int l,int r) {
        int max = Integer.MIN_VALUE;
        for(int i = l;i <= r;i++) {
            if(nums[i] > max) {
                max = nums[i];
            }
        }
        return max;
    }
法二(单调队列):

这个题目的核心目的就是维护一个滑动窗口,滑动窗口在滑动的时候,最左边的元素出窗口,出窗口的同时会有一个元素入窗口,每进行一次这个操作的时候就需要判断一下窗口内所有元素的最大值,并将最大值加入到一个数组中,滑动结束后返回数组;那么有没有一种数据结构可以在最左边弹出元素,最右边插入元素,而且内部的元素具有单调性,就很容易想到Java中的双端队列了,我们只需要在维护双端队列中的单调性即可,使得最大的元素永远在队列的最左边,这样每次加入到数组中的最大值永远是队列最左边的元素了

public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        int[] ans = new int[n - k + 1];
        Deque<Integer> q = new ArrayDeque<>(); // 双端队列
        for (int i = 0; i < n; i++) {
            // 1. 入队列
            while (!q.isEmpty() && nums[q.getLast()] <= nums[i]) {
                q.removeLast(); // 维护 q 的单调性(假设插入的元素比队列的最右边的元素大时,弹出最右边的元素)
            }
            q.addLast(i); // 入队
            // 2. 出
            if (i - q.getFirst() >= k) { // 队首已经离开窗口了
                q.removeFirst();
            }
            // 3. 记录答案
            if (i >= k - 1) {
                // 由于队首到队尾单调递减,所以窗口最大值就是队首
                ans[i - k + 1] = nums[q.getFirst()];
            }
        }
        return ans;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值