239. 滑动窗口最大值
第一想法
滑动窗口做这道题,这个窗口要存放的是从大到小的数值,每次添加元素都要判断队头元素是否超出滑动窗口范围,加进来的元素是否比队尾的元素更大。
代码
- 未封装
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q;
int n = nums.size();
vector<int> res;
for (int i = 0; i < k; i ++){
while(!q.empty() && q.back() < nums[i]) q.pop_back();
q.push_back(nums[i]);
}
res.push_back(q.front());
for (int i = k; i < n; i ++){
if (q.front() == nums[i - k]) q.pop_front();
while(!q.empty() && q.back() < nums[i]) q.pop_back();
q.push_back(nums[i]);
res.push_back(q.front());
}
return res;
}
};
- 封装
class Solution {
private:
class Myqueue{
public:
deque<int> q;
void pop(int value){
if (!q.empty() && q.front() == value) q.pop_front();
}
void push(int value){
while (!q.empty() && value > q.back()) q.pop_back();
q.push_back(value);
}
int front(){
return q.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
Myqueue q;
vector<int> res;
for (int i = 0; i < k; i ++) q.push(nums[i]);
res.push_back(q.front());
for (int i = k; i < nums.size(); i ++){
q.pop(nums[i - k]);
q.push(nums[i]);
res.push_back(q.front());
}
return res;
}
};
347. 前 K 个高频元素
第一想法
记录出现次数使用unordered_map
,如何统计出现次数排序,主要是对出现次数进行排序。一种是建立一个和给定数组大小一样大的数组,然后把出现过次数的放进去,从次数大到次数小数k个,把k对应的number放入返回数组。第二种使用优先队列,使用小根堆,这个堆里只放k个元素,如果超出k个元素,就要把小的pop掉,所以剩下的k个一定是最大的。如果是大根堆的话,就需要把所有的都排序,然后取出前k个,因为大根堆pop的话就是pop现有堆中最大的。
代码
- 数组记录
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int> res;
unordered_map<int, int> map;
for (auto num: nums) map[num] ++;
vector<int> s(nums.size() + 1, 0);
for (auto &m: map) s[m.second] ++;
int i = nums.size(), t = 0;
while (t < k) t += s[i--];
for (auto &p: map)
if (p.second > i) res.push_back(p.first);
return res;
}
};
- 小根堆
class Solution {
public:
class mycomparison{
public:
bool operator() (const pair<int, int>& i, const pair<int, int>& j){
return i.second > j.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> map;
priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> q;
vector<int> res(k);
for (auto num: nums) map[num] ++;
for (auto it = map.begin(); it != map.end(); it ++){
q.push(*it);
if (q.size() > k) q.pop();
}
for (int i = k - 1; i >= 0; i --){
auto a = q.top();
res[i] = a.first;
q.pop();
}
return res;
}
};
总结
栈和队列
栈和队列都是容器适配器,底层一般都是用deque来实现
栈
- 括号匹配
- 逆波兰表达式
- 字符串去重
队列
- 滑动窗口
- K个高频元素