题解 | #滑动窗口的最大值#

滑动窗口的最大值

http://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788

思路

根据题意: 要寻找每个滑动窗口的最大值,每次只滑一位 size等于0或者大于数组长度,都返回空值

方法一:暴力法 暴力解法应该是最容易想到的,只需要遍历数组的同时往后遍历每个窗口,找出最大值即可。

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
        vector<int> res;
        if(size <= num.size() && size != 0) //窗口大于数组长度的时候,返回空
            for(int i = 0; i <= num.size() - size; i++){//数组后面要空出窗口大小,避免越界
                int max = 0; //寻找每个窗口最大值
                for(int j = i; j < i + size; j++){
                    if(num[j] > max)
                        max = num[j];
                }
                res.push_back(max);
            }
        return res;
    }
};

复杂度分析

  • 时间复杂度:O(nm),其中n为数组长度,m为窗口长度,双层for循环
  • 空间复杂度:O(1),没有使用额外的空间,暂存的结果res不算入空间开销

方法二:双向队列法 暴力法重复计算了很多不必要比较。我们都知道,若是一个数字A进入窗口后,若是比窗口内其他数字都大,那么这个数字之前的数字都没用了,因为它们必定会比A早离开窗口,在A离开之前都争不过A,所以A在进入时要依次从后排除掉前面的小值。而当一个窗口最前的数字要离开时,是从前面离开。 因此一个双向队列可以解决这个问题。 图片说明 具体做法: 维护一个双向队列,用来存储数列的下标,如果即将进入队列的下标的值大于队列后方的值,依次将它们pop掉,再加入。如果某个下标已经过了窗口,则从队列前方将其pop掉。

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
        vector<int> res;
        if(size <= num.size() && size != 0){//窗口大于数组长度的时候,返回空
            deque <int> dq;  //双向队列
            for(int i =0; i < size; i++){
                while(!dq.empty() && num[dq.back()] < num[i]) //去掉比自己先进队列的小于自己的值
                     dq.pop_back();
                dq.push_back(i);
            }
            for(int i = size; i < num.size(); i++){
                res.push_back(num[dq.front()]);
                while(!dq.empty() && dq.front() < (i - size + 1))
                    dq.pop_front();  //弹出窗口移走后的值
                while(!dq.empty() && num[dq.back()] < num[i])
                    dq.pop_back();
                dq.push_back(i);
            }
            res.push_back(num[dq.front()]);
        }     
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n),只遍历一遍数组
  • 空间复杂度:O(m),窗口长度m,双向队列最长时,将窗口填满
孤帆远影碧空尽 文章被收录于专栏

牛客网各类题单题解~

全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
05-29 22:11
门头沟学院 Java
Elastic90:抛开学历造假不谈,这公司的招聘需求也挺怪的,Java开发还要求你有图文识别、移动端开发和c++的经验,有点逆天了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务