239. 滑动窗口最大值
思路:使用一个双向队列,实现单调队列,使其队头是当前窗口最大的值,并随着窗口的移动更新队头
class Solution {
private:
class myqueue//实现单调队列
{
public://这里calss默认为private,要声明是public,否则函数没法在myqueue之外使用
deque<int> de;//这个是双向队列
void push(int value)//添加元素,如果比尾部的大,把尾部的删掉,知道找到比value大的或者de为空
{
while(!de.empty()&&value>de.back())
{
de.pop_back();
}
de.push_back(value);
}
void pop(int value)//删除元素,在de不为空的情况下,如果value==de.front(),说明窗口已经不包括de.front(),要删去头
{
if(!de.empty()&&value==de.front())
{
de.pop_front();
}
}
int front()//放回队列的头
{
return de.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
myqueue que;
for(int i=0;i<k;i++)//先将前k个元素放进队列
{
que.push(nums[i]);
}
vector<int> res;
res.push_back(que.front());//前k个元素的最大值
for(int i=k;i<nums.size();i++)
{
que.pop(nums[i-k]);//删去出窗口的元素
que.push(nums[i]);//将新进窗口的元素入队
res.push_back(que.front());//在答案中加入当前窗口的最大值
}
return res;
}
};
这里再复习一下双向队列的用法
# include<deque>//deque定义在 <deque> 头文件中,并位于 std 命名空间内
using namespace std;
int mian()
{
deque<int> dp;//生成
dp.front();//返回队头元素
dp.back();//返回队尾元素
dp.push_front(1);//头插入
dp.push_back(2);//尾插入
dp.pop_front();//头删除
dp.pop_back();//尾删除
dp.size();//返回容量
dp.empty();//判空
dp.clear();//清空
}
347. 前 K 个高频元素
这里使用优先队列实现小顶堆,将小顶堆的容量控制在k个,超出的话删去根节点(即最小的那个)
小顶堆(最小堆)
在小顶堆中,任何父节点的键值都不大于其子节点的键值。这意味着树的根节点是所有节点中具有最小键值的节点。小顶堆的这个特性保证了可以快速地找到最小元素(在堆中即为树的根节点)。
大顶堆(最大堆)
在大顶堆中,任何父节点的键值都不小于其子节点的键值。这意味着树的根节点是所有节点中具有最大键值的节点。大顶堆保证了可以快速地找到最大元素。
代码:
class Solution {//注意map要排序需要先转换为vector
public:
class compare//定义一个比较方法,实现小顶堆
{
public:
bool operator()(const pair<int,int>&a,const pair<int,int> &b)//重载()运算符,如果对于运算符重载不熟悉,可以看看c++ prime plus 的第十一章
{
return a.second>b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> arr;//存储每个元素出现的次数
for(int i=0;i<nums.size();i++)arr[nums[i]]++;
priority_queue<pair<int,int>,vector<pair<int,int>>,compare> pri_que;
for(unordered_map<int,int>::iterator st=arr.begin();st!=arr.end();st++)//遍历arr
{
pri_que.push(*st);
if(pri_que.size()>k)//如国pri_que的容量超过了k,那么将最小的根节点删去
{
pri_que.pop();
}
}
vector<int> res;
for(int i=k-1;i>=0;i--)//将前k个元素转移至vector中
{
res.push_back(pri_que.top().first);
pri_que.pop();
}
return res;
}
};
#include <queue>
/*priority_queue 生成*/
priority_queue<int> q; //大根堆
priority_queue<int, vector<int>, greater<int>> q; //小根堆
/*priority_queue 插入*/
q.push(2); //把一个元素插入堆
/*priority_queue 删除*/
q.pop(); //删除堆顶的元素
/*priority_queue 堆顶*/
q.top(); //返回堆顶元素
/*priority_queue 容量*/
q.size();
/*priority_queue 判空*/
q.empty()