剑指offer59队列的最大值(不熟)
Posted shiganquan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer59队列的最大值(不熟)相关的知识,希望对你有一定的参考价值。
题目一
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,{2,3,4,2,6,2,5,1}以及窗口大小3,那么存在6个滑动窗口,最大值分别为{4,4,6,6,6,5} 滑动
思路
滑动窗口可以看作是队列,为了得到滑动窗口的最大值,队列可以从两端删除元素,因此使用双向队列。
原则:对于新来的元素k,将其与队列中元素比较,
1、若队列中有元素比k小,直接将之前比k小的元素移除队列(因为不可能再成为后面滑动窗口的最大值),压入k
2、若队列中元素x比k大,则根据下标检测x是否在窗口内,如果不在则移除队列,压入k
队列的第一个元素是滑动窗口的最大值,同时要存储数字在数组的下标,而不是数值,用来判断滑动窗口是否包含数字
举例说明:
1、将2压入队列
2、3比2大,弹出2,压入3
3、4比3大,弹出3,压入4
4、2比4小,4还在窗口内,保留4,压入2
5、6比4和2都大,因此弹出4和2,压入6
6、2比6小,6在窗口内,保留6,压入2
7、5比2大,比6小,且6还在窗口内,弹出2,压入5
8、1比6和5都小,但是6不在窗口内,6弹出,压入1
class Solution { public: vector<int> maxInWindows(const vector<int>& num, unsigned int size) { vector<int> max_in_win; if (num.size() >= size && size >= 1) { deque<int> index; // 存的是索引 for (unsigned int i = 0; i < size; i++) // 先把size-1个元素压入队列,此时还不构成窗口 { 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_in_win.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_in_win.push_back(num[index.front()]); } return max_in_win; } };
题目二
请定义一个队列并实现函数max得到队列里的最大值,要求函数max,push_back,pop_front的时间复杂度都是O(1)
思路
滑动窗口可以看作队列,因此定义两个队列data和maximum
以上是关于剑指offer59队列的最大值(不熟)的主要内容,如果未能解决你的问题,请参考以下文章
剑指offer59 - II 至 剑指offer 64 题解
剑指offer59 - II 至 剑指offer 64 题解
乱序版 ● 剑指offer每日算法题打卡题解——栈与队列(题号59)