Arithmetic problem | 找到数组中滑动窗口内的最大值

题目如下:

给出一个可能包含重复的整数数组,和一个大小为 k 的滑动窗口, 从左到右在数组中滑动这个窗口,找到数组中每个窗口内的最大值。O(n)时间,O(k)的额外空间


样例

给出数组 [1,2,7,7,8], 滑动窗口大小为 k = 3. 返回 [7,7,8].

解释:

最开始,窗口的状态如下:

[|1, 2 ,7| ,7 , 8], 最大值为 7;

然后窗口向右移动一位:

[1, |2, 7, 7|, 8], 最大值为 7;

最后窗口再向右移动一位:

[1, 2, |7, 7, 8|], 最大值为 8.


解题思路:

O(n)的复杂度明显需要缓存,每个窗口间都存在并集部分,那么并集部分的最大值当然就是缓存了。至于遍历,我们可以像下图一样(m1,m2,m3为所在窗口最大值):


由于我们需要的只是缓存里的最大值,只要在保证缓存的最大值在窗口有效区间内,那么该最大值也就是该窗口的最大值了。显然,排序缓存是不可靠的提取最大值方法,除开复杂度提升问题不说,缓存里存储的数组下标也跟排序不相衬,并且缓存里的非区间最大值也许永远都用不上,因此,我们采取压榨区间来提取最大值。采用双向列表的优势,不停把最后元素与目前遍历处理的元素相比较,少于则popback,直到列表back元素大于它,大于则pushback,这样,我们可以确保,列表任意两个元素组成的区间内的元素都比这两个元素要小。只要列表最前元素在区间内,此元素也就是该区间最大值,不在,则下一个元素是最大值。


思路代码实现如下:

void Method(int *s,int len,int k)
{
    deque<short>d;int i;
    for(i=0;i<len;++i)
    {
        if(!d.empty()&&d.front()==i-k)
            d.pop_front();
        while(!d.empty()&&d.back()<s[i])
            d.pop_back();
        d.push_back(i);
        if(i>=k-1)
            printf("%d ",s[d.front()]);
    }
}


  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值