博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(笔试题)滑动窗口的最大值
阅读量:4982 次
发布时间:2019-06-12

本文共 2544 字,大约阅读时间需要 8 分钟。

题目:

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。

例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5};

针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:

{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路:

假设窗口大小为w,

1、简单的方法:

遍历数组,从数组第w-1位开始,每次移动一位,并计算窗口w的最大值。

时间复杂度:

计算窗口的最大值需O(w),移动n-w+1次,时间复杂度为O(nw)

2、最大堆方法:

构建一个窗口w大小的最大堆,每次从堆中取出窗口的最大值,随着窗口往右滑动,需要将堆中不属于窗口的堆顶元素删除。

时间复杂度:

正常情况下,往堆中插入数据为O(lgw),如果数组有序,则为O(lgn),因为滑动过程中没有元素从堆中被删除,滑动n-w+1次,复杂度为O(nlgn).

3、双队列方法:

最大堆解法在堆中保存有冗余的元素,比如原来堆中元素为[10 5 3],新的元素为11,则此时堆中会保存有[11 5 3]。其实此时可以清空整个队列,然后再将11加入到队列即可,即只在队列中保持[11]。使用双向队列可以满足要求,滑动窗口的最大值总是保存在队列首部队列里面的数据总是从大到小排列。当遇到比当前滑动窗口最大值更大的值时,则将队列清空,并将新的最大值插入到队列中。如果遇到的值比当前最大值小,则直接插入到队列尾部。每次移动的时候需要判断当前的最大值是否在有效范围,如果不在,则需要将其从队列中删除。由于每个元素最多进队和出队各一次,因此该算法时间复杂度为O(N)。

代码:

1、简单方法:

int getMax(const int A[],int size){    int mx=A[0];    for(int i=1;i
mx) mx=A[i]; } return mx;}vector
maxInWindows(const int A[],int n,int size){ vector
result; for(int i=0;i

2、最大堆、双队列方法

class Solution {    public:        //最大堆实现,复杂度O(nlogn)    typedef pair
Pair; vector
maxInWindows(const vector
&num, unsigned int size) { vector
result; priority_queue
Q; if (num.size() < size || size < 1) return result; for (int i = 0; i < size-1; i++) Q.push(Pair(num[i],i)); for (int i = size-1; i < num.size(); i++) { Q.push(Pair(num[i],i)); Pair p = Q.top(); while(p.second < i-(size-1)) { Q.pop(); p = Q.top(); } result.push_back(p.first); } return result; } // 双向队列实现,复杂度O(n) vector
maxInWindows(const vector
&num, unsigned int size) { vector
result; deque
Q;// int n = num.size(); if(num.size()
num[Q.back()]) Q.pop_back(); Q.push_back(i); } for (int i = size; i < num.size(); i++) { result.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(); Q.push_back(i); } result.push_back(num[Q.front()]); return result; } };

转载于:https://www.cnblogs.com/AndyJee/p/4483639.html

你可能感兴趣的文章
一对一双向外键关联
查看>>
EL表达式概述
查看>>
javascript面向对象学习笔记(一)——继承
查看>>
python调试
查看>>
Selenium3+Python3_02:元素定位
查看>>
SpringMVC中的拦截器
查看>>
【转】如何将ACCESS数据库后缀名accdb改为mdb
查看>>
Debug : array type has incomplete element type
查看>>
代码腐化之路
查看>>
InnoDB 主键的选择:自增ID & 业务ID
查看>>
联系人数据库设计之ContactsTransaction
查看>>
如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话
查看>>
无参函数的调用
查看>>
【记录】GIT 常用命令记录
查看>>
HDU 4770 Lights Against Dudely(暴力+状压)
查看>>
faceted project validation builder
查看>>
一些常见的Java面试题 & 面试感悟
查看>>
使用CEF类库处理HTTP请求
查看>>
SDWebImage 图片加载和缓存
查看>>
UIControl
查看>>