滑动窗口最大值
leetcode:239. 滑动窗口最大值
第一个hard!work out!资源占用竟然如此之大,,
单调队列法
思路
需要一个抽象的类队列数据结构,每轮移动时:1. 把队首pop;2.把下一元素push进队尾;3.获取队列最大值存入数组。
pop实现:每次移动时尝试(说“尝试”是因为可能已经弹出了)弹出队首元素(条件是队列非空且val==que.front
)。
push实现:每次移动放入下一元素。放入元素前,从队尾弹出所有小于该元素的值。
getMax实现:返回队首。
复杂度分析
时间复杂度:O(N)。
空间复杂度:O(K)。队列最多有K个元素。
注意点
- 这只是单调队列的一种实现(只要保证队列单调递减或递增就是单调队列),实现写法不固定。
- deque是c++中stack和queue的底层实现容器,首尾都可以进出。
- vector可以push_back。
- c++对象声明不需要new(直接声明是生命周期在作用域内,内存从栈上分配;new分配的声明周期在new~delete之间,内存从堆上分配)。new的对象需要指针类型保存,访问时候用->。
代码实现
class Solution {
private:
class myQue{
public:
deque<int> que;
void pop(int val){
// 每次移动尝试弹出最左侧的元素
// 只有val==队首时候弹出(其他元素在push的时候就已经弹出了)
if(!que.empty() && val == que.front()){
que.pop_front();
}
}
void push(int val){
// 队尾插入,插入前弹出所有比val小的元素
while(!que.empty() && val > que.back()){
que.pop_back();
}
que.push_back(val);
}
int getMax(){
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
myQue que;
vector<int> result;
// 装填k个元素
for(int i = 0;i < k;i++){
que.push(nums[i]);
}
// 获取前k个元素最大值
result.push_back(que.getMax());
// 移动size-k次
for(int i = k;i < nums.size();i++){
que.pop(nums[i - k]);
que.push(nums[i]);
result.push_back(que.getMax());
}
return result;
}
};
前k个高频元素
leetcode:347. 前 K 个高频元素
优先队列法
思路
- 遍历数组用map记录元素出现聘书
- 遍历map用小堆顶(优先队列)来存储前k个元素。
- 倒序遍历结果数组,把优先队列倒序赋值进去。
复杂度分析
时间复杂度:O(N)。N大小的数组、map遍历各1次、k大小的数组遍历1次。
空间复杂度:O(N+K)。
注意点
- map等无下标容器用iterator遍历,迭代器加星号*可以取迭代器对应的值。
- 优先队列没有front只有top。
- 仿函数(Function Object/Functor)是指可以通过函数调用操作符'
( )
'执行的对象。具体来说是任何定义了'operator()
'的类的实例,使得类的对象可以像函数一样调用,因此得名“仿函数”。
代码实现
class Solution {
private:
class myComparision{
public:
bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
return lhs.second > rhs.second;
}
};
public:
// 用map试试
// 遍历,用map记录元素出现频数
// 小堆顶存储k个元素
// 数组倒序存储结果
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> map;
for(int i = 0;i < nums.size();i++){
map[nums[i]]++;
}
priority_queue<pair<int,int>,vector<pair<int,int>>,myComparision> minPq;
for(unordered_map<int,int>::iterator it = map.begin();it != map.end();it++){
minPq.push(*it);
if(minPq.size() > k)
minPq.pop();
}
vector<int> result(k);
for(int i = k-1;i >= 0;i--){
result[i] = minPq.top().first;
minPq.pop();
}
return result;
}
};
标签:map,13,队列,最大值,元素,60,int,que,push
From: https://www.cnblogs.com/tazdingo/p/18009023