这里写目录标题
239. 滑动窗口最大值
1.题目描述
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值
2.思路分析:使用单调队列
1.用一个单调队列队列维护当前窗口最大值和同时保证队列里面元素由大到小排列
2.遍历数组,在队列放入当前遍历到的元素,如当前元素大于队列尾部元素则把小于当前元素的值都弹出。
3.单调队列弹出队头的条件不是que.size()为==k, 而是当前队头的值等于滑动窗口滑出的值 que.front()等于nums[i-k]
3.代码.思路分析:使用单调队列
class Solution {
public:
deque<int>que;
vector<int>output;
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(k==1)return nums;
for(int i=0;i<k;i++)
{
while(!que.empty()&&que.back()<nums[i])
{
que.pop_back();
}
que.push_back(nums[i]);
}
output.push_back(que.front());
for(int i=k;i<nums.size();i++)
{
if(que.front()==nums[i-k])que.pop_front();//单调队列弹出队头的条件
while(!que.empty()&&que.back()<nums[i])
{
cout<<que.back()<<" ";
que.pop_back();
}
que.push_back(nums[i]);
cout<<que.back()<<endl;
output.push_back(que.front());
}
return output;
}
};
347. 前 K 个高频元素
1.题目描述
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
2.思路分析:
方法一:用map,vector进行排序
1.将数组里的元素存放在map里,value存放元素出现的次数
2.将map里的数放入vector数组,通过sort用value进行排序
3.sort里面的排序重写static bool cmp( , )
方法二:用优先队列进行排序
1.什么是优先队列—模板类priority_queue,包含在头文件里
优先队列的本质是堆,但它具有队列的所有操作特性,与普通队列不同的地方就是出队的时候按照优先级顺序出队,这个优先级即最大堆或最小堆的规则(即大的为top优先出队或小的为top优先出队),在队列的基础上加了个堆排序。以O(log n) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质来决定的
2.优先队列的语法
priority_queue<Type, Container, Functional>
其中Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
1.在STL中,默认情况下(不加后面两个参数)是以vector为容器,以 operator< 为比较方式,所以在只使用第一个参数时,优先队列默认是一个最大堆。
2.用到最小堆,则一般要把模板的三个参数都带进去。STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明最小堆(升序)
3.大顶堆与小顶堆,需要注意的是,如果使用less和greater,需要头文件:#include
//构造一个空的优先队列(此优先队列默认为大顶堆,大顶堆为降序)
priority_queue<int> big_heap;
//另一种构建大顶堆的方法
priority_queue<int,vector<int>,less<int> > big_heap2;
/构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;
注意事项
需要注意的是,如果使用less和greater,需要头文件:
//重载比较运算
#include <functional>
struct Node{
int x,y;
Node(int a=0, int b=0):
x(a), y(b) {}
};
struct cmp{
bool operator()(Node a, Node b){
if(a.x == b.x) return a.y>b.y;
return a.x>b.x;
}
};
优先队列比较顺序相反
3.代码.思路分析:
方法一:
class Solution {
public:
unordered_map<int,int>into;
vector<int>output;
static bool cmp(pair<int,int>a,pair<int,int>b)
{
return a.second>b.second;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
for(int i=0;i<nums.size();i++)
{
into[nums[i]]++;
}
vector<pair<int,int>>into_ope(into.begin(),into.end());
sort(into_ope.begin(),into_ope.end(),cmp);
for(int i=0;i<k;i++)
{
output.push_back(into_ope[i].first);
}
return output;
}
};
方法二
class Solution {
public:
struct cmp {
bool operator()(pair<int,int>a,pair<int,int>b){
return a.second>b.second;//与对比相反,返回的是小堆
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int,int>into;
for(int i=0;i<nums.size();i++)
{
into[nums[i]]++;
}
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>prique;
for(auto itt:into)
{
prique.push(itt);
if(prique.size()>k)prique.pop();//因为排的是小堆,从顶部弹出的是最小的值
}
vector<int>output;
while(!prique.empty())
{
output.push_back(prique.top().first);
prique.pop();
}
return output;
}
};