zoukankan      html  css  js  c++  java
  • LeetCode239. 滑动窗口最大值

    暴力做法:可以在遍历数组的时候,当i-k+1>=0(表示当前滑动窗口的大小达到了k),就遍历i-k+1 ~ i的所有元素,寻找最大值,
    然后把最大值压入到结果数组res中,显然这种做法需要两重循环,时间复杂度为O(n*k)。

    我们考虑一下优化,暴力做法在遍历数组的时候还需要在内层循环遍历来计算当前窗口内的最大值,而计算当前窗口的最大值,我们可以用
    单调队列进行优化。

    考虑这样一种情况:在长度为k的滑动窗口内,我们要寻找最大值:我们可以从前往后寻找,如果有这样一种情况,下标i < j,且nums[i] <= nums[j],
    则nums[i]肯定不是答案,因为nums[j]比nums[i]大。
    不过在下一次遍历数组的时候,又(可能)在下一个滑动窗口内比较nums[i]和nums[j]了,虽然我们在之前就知道了只要有nums[j]在,nums[i]就肯定
    不是答案了。
    所以我们可以用单调队列来记录某个滑动窗口内的元素的大小关系,把当前窗口内的元素入队(其实是把下标入队),每个元素入队之前都会和队尾元素进行比较,
    如果当前元素比队尾元素大,则队尾元素肯定不是当前滑动窗口内的最大值(当然也不会是后面的滑动窗口的最大值),我们就一直删除队尾元素,直到队列
    为空或者队尾元素比当前元素大。这时再把当前元素(的下标)入队,这样,我们的队列里的元素(下标)的值(nums[下标])就是单调递减的,所以队头元素
    就是当前滑动窗口内的最大值。
    我们只需要注意当滑动窗口移动的时候判断窗口左端(i - k + 1)和队头元素的关系,如果i - k + 1大于q.front(),说明当前
    窗口滑动到下一个位置,之前记录的队头元素下标已经过期了,那就要出队。
    通过这种方式,我们就维护了一个能够快速找到当前滑动窗口内元素最大值的双端队列。

    时间复杂度分析:由于遍历一遍数组,每个元素最多入队和出队一次,所以时间复杂度为O(n)。

    代码如下:

    class Solution {
    public:
        vector<int> maxSlidingWindow(vector<int>& nums, int k) {
            vector<int> res;
            deque<int> q;                                          //双端队列里存的是下标,不是值
            for(int i = 0; i < nums.size(); ++i) {
                if(q.size() && q.front() < i - k + 1) {                  //窗口滑动,之前的队头元素过期了,出队
                    q.pop_front();
                }
                while(q.size() && nums[q.back()] <= nums[i]) {           //当前元素比之前队列记录的队尾元素大,则队尾元素出队,因为他肯定不是答案
                    q.pop_back();
                }
                q.push_back(i);
                if(i - k + 1 >= 0) {                                    //如果窗口大小已经为k,则肯定有一个最大值,记录到res数组中
                    res.push_back(nums[q.front()]);
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    使用nodejs消费SAP Cloud for Customer上的Web service
    如何在SAP Cloud for Customer自定义BO中创建访问控制
    SAP云平台运行环境Cloud Foundry和Neo的区别
    SAP成都研究院马洪波:提升学习力,增强竞争力,收获一生乐趣
    SAP Netweaver的负载均衡消息服务器 vs CloudFoundry的App Router
    写在Github被微软收购之际
    在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
    Java实现 LeetCode 517 超级洗衣机
    Java实现 LeetCode 517 超级洗衣机
    Java实现 LeetCode 517 超级洗衣机
  • 原文地址:https://www.cnblogs.com/linrj/p/13540339.html
Copyright © 2011-2022 走看看