滑动窗口最大值
题目链接:力扣
知识点:单调队列
解题思路:
需要一个队列,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。
其实队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。
设计单调队列时,需要保持的规则:
pop(value):
如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
push(value):
如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
front():
保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
class MY_Queue //为一个单调队列
{
deque<int> MyQueue;
public:
void pop(int value) //弹出元素
{
if(!MyQueue.empty() && value == MyQueue.front()) //窗口移除的元素value等于单调队列的出口元素
MyQueue.pop_front();
}
void push(int value) //加入元素 维护出口处的最大值
{
while(!MyQueue.empty() && value > MyQueue.back())
MyQueue.pop_back();
MyQueue.push_back(value);
}
int front() //队列首元素,及最大值
{
return MyQueue.front();
}
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> Res;
MY_Queue MQ;
for(int i = 0; i<k; i++) //先将前k个元素放入
MQ.push(nums[i]);
Res.push_back(MQ.front());
for(int i=k ;i<nums.size();i++)
{
MQ.pop(nums[i-k]);
MQ.push(nums[i]);
Res.push_back(MQ.front());
}
return Res;
}
};
前 K 个高频元素
题目链接:力扣
解题思路:
1、如何求得数组中每个元素的频率 —— map (key存放元素,value存放出现次数)
2、如何对这个频率进行排序,并求前K个高频的元素 —— 大顶堆(父亲比孩子大)、小顶堆(父亲比孩子小)遍历map中的所有元素,并以value为基准进行统计,同时该堆只维护堆中的k个元素。
这里选择小顶堆,因为遇到较大的元素时,采用pop将堆中原来的最小元素移除,再push将该元素放入,这样留下的就是较大的元素。
在CPP中,可以选用优先级队列,即priority_queue
由于要使用小顶堆,所以需要定义一个比较函数,用于确定元素的优先级。
在这个定义中,使用了一个名为mycomparison
的自定义比较函数对象。
//小顶堆
class mycomparison{
public:
bool operator()(const pair<int, int>&lhs, const pair<int, int>&rhs)
{
return lhs.second > rhs.second;
}
};
接下来的代码中,定义了自定义的优先级队列 pri_que
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparisom> pri_que;
具体来说,这个优先队列 pri_que
的定义包括以下几个部分:
-
pair<int, int>
:表示队列中的元素类型为存储两个整数值的pair对象。每个pair对象有两个成员,分别命名为first
和second
,在这里分别表示整数值的第一个和第二个元素。 -
vector<pair<int, int>>
:作为优先队列的底层容器类型,使用vector
来存储元素。这意味着优先队列中的元素将以向量的形式进行存储。 -
mycomparison
:是一个自定义的比较函数对象(Comparator),用于确定元素的优先级。在这个定义中,使用了一个名为mycomparison
的自定义比较函数对象。
总的来说,这段代码定义了一个基于pair<int, int>
类型的优先队列pri_que
,底层使用vector
作为容器,同时使用自定义的比较函数mycomparison
来确定元素的优先级。
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int>Mymap;
vector<int> Res(k);
for(int i=0; i<nums.size();i++)
{
Mymap[nums[i]]++; //得到各元素的频率
}
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparisom> pri_que;
for(auto it = Mymap.begin(); it != Mymap.end(); it++)
{
pri_que.push(*it);
if(pri_que.size() > k)
pri_que.pop();
}
for(int i=k-1;i>=0;i--)
{
Res[i] = pri_que.top().first;
pri_que.pop();
}
return Res;
}