剑指offer 59 滑动窗口的最大值以及 队列流中的最大值

题目描述

给定一个数组A[],有一个大小为w的滑动窗口,该滑动窗口从最左边滑到最后边。在该窗口中你只能看到w个数字,每次只能移动一个位置。我们的目的是找到每个窗口w个数字中的最大值,并将这些最大值存储在数组B中。

例如数组A=[1 3 -1 -3 5 3 6 ], 窗口大小w为3。则窗口滑动过程如下所示:

Window position              Max
---------------             -----
[1  3  -1] -3  5  3  6        3
 1 [3  -1  -3] 5  3  6        3
 1  3 [-1  -3  5] 3  6        5
 1  3  -1 [-3  5  3] 6        5
 1  3  -1  -3 [5  3  6]       6
 

输入参数为数组A和w大小

输出为数组B,其中B[i]存储了A[i]到A[i+w-1]中w个数字的最大值。

思路:

利用一个双端队列,保存滑动窗口中的有可能成为最大值的下标。然后随着滑动窗口的移动,不断跟更新队尾和队首.

而每次窗口移动都将队首压入最大值数组。

以下面例子讲解具体过程:

数组A=[1 3 -1 -3 5 3 6 7], 窗口大小w为3

代码:

 vector<int>  MaxInWndows(const vector<int>&num,unsigned int size)

{ 

vector<int>max;

if(num.size()>=size&&size>=1)

{

deque<int>index;
for(unsigned int i=0;i<size;i++)

{   
 while(!index.empty()&&num[i]>=num[index.back()])

 index.pop_back();

 index.push_back(i);
}

for(unsigned int i=size;i<num.size();i++)

{   
 max.push_back(num[index.front()];

 while(!index.empty()&&num[i]>=num[index.back()])

 index.pop_back();

 if(!index.empty()&&index.front()<=(int)(i-size))

  index.pop_front();

 index.push_back(i);

}

max.push_back(num[index.front()];

}

return max;

}

题目二:

队列的最大值

请定义一个队列并实现函数max得到队列里的最大值,要求函数max、push_back和pop_front的时间复杂度都是O(1)

此题的意思就是,假如有一家很火爆的店,店外不断有人排队离队,请你用队列这个数据结构展示目前排队的状态,即任何时刻队列里的最大值(可以想象成队列里最高的人)

思路:

  • 同上一题相同,我们要寻找队列的最大值,相当与将滑动窗口设置为整个队列。
  • 这里需要使用两个队列,一个队列用来保存入队的数据,一个队列用来保存队列的当前最大值。
  • 其中两个队列中的数据都是一对值(元素值和其索引)
  • 同时需要注意出队操作,数据队列出队的同时需要判断其索引是否和当前最大值队列首部索引相同,如果相同则同时也将最大值队列头部出队。

template<typename T>class QueueWithMax

{

private:

struct Data

{ T number;

  int index;

};

deque<Data>data;

deque<Data>max;

int curindex;

public:

QueueWithMax():curindex(0)

{}//初始化curindex

//当队尾有人排队时,更新队中最大值,所以我们必须维护两个队列,一个用于保存整个队列的数据,一个用于保存最大值

void push_back(T number)

{

while(!max.empty()&&number>=max.back().number)

max.pop_back();

Data d={number,curindex);

data.push_back(d);

max.push_back(d);

++curindex;

}

//当队首有人离开时,更新data和max的值,当data的队首和max的队首相同时,则max也需要pop_front,

 否则只需要data pop_front

void pop_front()

{

if(max.empty())

throw new exception("queue is empty");

if(max.front().index==data.front().index)

max.pop_front;

data.pop_front;

}

T max()const

{ if(max.empty())

throw new expection("queue is empty");

return max.front().number;

}

};

猜你喜欢

转载自blog.csdn.net/weixin_41413441/article/details/80689518