-
queue 队列 不可以通过迭代器访问
front() 返回第一个元素的引用。 back() 返回最后一个元素的引用。 push() 在序列的尾部添加一个元素。 pop() 移除容器头部的元素。
-
deque 双端队列 可以通过迭代器访问
front() 返回第一个元素的引用。 back() 返回最后一个元素的引用。 push_back() 在序列的尾部添加一个元素。 push_front() 在序列的头部添加一个元素。 pop_back() 移除容器尾部的元素。 pop_front() 移除容器头部的元素。
-
priority_queue 优先队列 不可以通过迭代器访问
top() 返回第一个元素的引用。 push() pop() 移除 priority_queue 容器适配器中第一个元素。 priority_queue<int, vector<int>, less<int>> pq; // 最大堆 priority_queue<int, vector<int>, greater<int>> pq; // 最小堆 priority_queue<ListNode*, vector<ListNode*>, cmp> pq; priority_queue自定义函数的比较与sort正好是相反的 也就是说,如果你是把大于号作为第一关键字的比较方式,那么堆顶的元素就是第一关键字最小的 struct cmp{ bool operator()(const ListNode* a, const ListNode* b){ return a->val > b->val; } };
题目:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
思路:
1. 需要维持一个有可能成为窗口最大元素就可以
2. 窗口就是先进先出 那么我们需要一个队列
3. 假定 当前元素为 1 下一个存进来地元素 是5 那么 1就不可能是该窗口的最大值
所以这个队列里的元素保持单调递减 5 4 3 2 1
5出队 4 是最大值 4 出队 3是最大值
4. 那么新进队的元素应该与队尾元素进行比较,队尾元素小就要一直出队,从队尾出队,使用到双头队列 deque
5. 具体操作: 维持一个单调递减的队列,如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止,移除元素时,如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int>q;
vector<int>result;
int start = 0;
int end = start;
while(end < nums.size()){
while(!q.empty() && nums[end] > q.back()){
q.pop_back();
}
q.push_back(nums[end]); //保证队列单调
end++;
if(end - start == k){
result.push_back(q.front());
if(nums[start] == q.front()){ //维持当前窗口的最大值
q.pop_front();
}
start++;
}
}
return result;
}
};
思路: 1. 用map 进行统计 2. 用最大最小堆进行排序
关键: 用最大堆还是最小堆
当元素元素特别多,但是k很小时,维持一个k的最小堆来省空间。小顶堆每次将最小的元素弹出,最后小顶堆里积累的就是前k个最大元素。
class Solution {
public:
struct cmp{
bool operator()(const pair<int, int>&a, const pair<int, int>&b){
return a.second > b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int>mp;
for(int i = 0; i < nums.size(); i++){
mp[nums[i]]++;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp>q;
for(pair<int, int>x : mp){
if(q.size() >= k && q.top().second < x.second){
q.pop();
q.push(x);
}else if(q.size() < k){
q.push(x);
}
}
vector<int>reslut;
while(!q.empty()){
reslut.push_back(q.top().first);
q.pop();
}
return reslut;
}
};
class Solution {
public:
priority_queue<int, vector<int>, less<int>>m_in; //放着小于等于中位数的元素
priority_queue<int, vector<int>, greater<int>>m_ax; //大于中位数
void Insert(int num) {
if (m_in.empty() || m_in.top() >= num) {
m_in.push(num);
//我们要维持min.size()-max.size()<2;
if (m_in.size() - m_ax.size() >= 2) {
m_ax.push(m_in.top());
m_in.pop();
}
} else {
m_ax.push(num);
if (m_ax.size() - m_in.size() >= 1) {
m_in.push(m_ax.top());
m_ax.pop();
}
}
}
double GetMedian() {
if(m_in.size() - m_ax.size() == 1) return double(m_in.top());
return (m_in.top() + m_ax.top())/2.0;
}
};