栈与队列 Part III
滑动窗口最大值 高频元素
滑动窗口最大值
法1:
class Solution {
//构造单调队列 按要求存取val
private:
class SingleQueue{
public:
deque<int> myqueue;
void pop(int val){
if (!myqueue.empty() && val == myqueue.front())
myqueue.pop_front();
}
void push(int val){
while (!myqueue.empty() && val > myqueue.back()) {//此处使用的是while()循环
myqueue.pop_back();
}
myqueue.push_back(val);
}
int front(){
return myqueue.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
SingleQueue sq;
vector<int> result;
for (int i = 0; i < k; ++i) {
sq.push(nums[i]);
}
result.push_back(sq.front());
//使用for循环进行窗口移动
int len = nums.size();
for (int i = k; i < len; ++i) {
sq.pop(nums[i-k]);
sq.push(nums[i]);
result.push_back(sq.front());
}
return result;
}
};
前k个高频元素
347.前 K 个高频元素
法1: 暴力求解
typedef pair<int,int> PAIR;
struct CmpByVal{
bool operator()(const PAIR& lhs,const PAIR& rhs){
return lhs.second >= rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
// 统计每个元素出现个数
map<int, int> frequency;
for (int& num : nums) {
frequency[num]++;
}
// 根据元素出现个数从大到小排序
vector<pair<int, int>> freVec(frequency.begin(), frequency.end());
sort(freVec.begin(), freVec.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {
return p1.second > p2.second;
});
// 将前k个元素放进结果数组
vector<int> ans(k);
transform(freVec.begin(), freVec.begin() + k, ans.begin(), [](const auto& p) {
return p.first;
});
return ans;
}
法2:
基本概念: 大顶堆/小顶堆
堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
class mycomparsion {
public:
bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
return lhs.second > rhs.second;//按val进比较
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
// 统计每个元素出现个数
unordered_map<int, int> frequency;
for (int& num : nums) {
frequency[num]++;
}
//小顶堆
priority_queue< pair<int,int>,vector<pair<int,int>>,mycomparsion> pri_que;
// priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;
// 用固定大小为k的小顶堆,扫面所有频率的数值
for(unordered_map<int,int>::iterator it = frequency.begin();it != frequency.end();it++){
pri_que.push(*it);
if (pri_que.size() > k)
pri_que.pop();
}
// 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
vector<int> ans(k);//构造函数使用k初始化 创建vector
for (int i = k-1; i >=0; --i) {
ans[i] =pri_que.top().first;
pri_que.pop();
}
return ans;
}