c++滑动窗口最大值

前提:数组长度为n,窗口大小为k。

暴力的时间复杂度是O(nk)

	vector<int> comp(vector<int> v)
    {
        vector<int> ans;
        for(int i = 0; i+1 < v.size(); i++)
            ans.push_back(max(v[i],v[i+1]));
        return ans;
    }
    vector<int> maxInWindows(vector<int>& num, unsigned int size)
    {
        if(size == 1) return num;
        vector<int> ans;
        for(int i = 1; i < size; i++)
            if(i == 1) ans = comp(num);
            else ans = comp(ans);
        return ans;
    }

此时获取窗口中的最大值的复杂度为O(k)。
那么如何将O(k)的复杂度变为O(1)是我们该考虑的地方。
我们可以将双端队列deque作为滑动窗口。deque内部,要保证元素非严格递减,则deque[0]是当前窗口的最大值。
那么每次窗口滑动,将删除deque的内部对应的元素,添加新元素k,并将小于k的元素删除。

    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        if(size == 1) return num;
        vector<int> ans;
        deque<int> q;//维护每个窗口最大值的下标
        if(num.size() < size || size == 0) return ans;
        for(int i = 0; i < size; i++){//初始化窗口
            while(!q.empty() && num[i] > num[q.back()]) q.pop_back();
            q.push_back(i);
        }
        for(int i = size; i < num.size(); i++){
            ans.push_back(num[q.front()]);//当前窗口的最大值
            while(!q.empty() && num[i] >= num[q.back()]) q.pop_back();//新添加的元素大于队列最后一个
            while(!q.empty() && q.front() <= i-size) q.pop_front();//判断队首元素是否过期(在窗口外)
            //i-q.front()>=size  ,size是无符号类型
            q.push_back(i);
        }
        ans.push_back(num[q.front()]);
        return ans;
    }

此时,时间复杂度为O(n),空间复杂度为O(k).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值