优先级队列
#include<queue> --队列 和 优先级队列的头文件优先级队列: 堆结构 最大堆 和 最小堆
相关函数:
front() 获取第一个元素
back() 获取最后一个元素
push() 放入元素
pop() 弹出第一个元素
size() 计算队列中元素的个数
empty() 判断是否为空 为空返回true 不为空返回false
石头的重量
1046. 最后一块石头的重量https://leetcode.cn/problems/last-stone-weight/
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x
和 y
,且 x <= y
。那么粉碎的可能结果如下:
- 如果
x == y
,那么两块石头都会被完全粉碎; - 如果
x != y
,那么重量为x
的石头将会完全粉碎,而重量为y
的石头新重量为y-x
。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0
。
思路
利用优先级,队列默认最大堆结构将数组中元素升序排一下,然后每次取出堆顶元素和堆顶下一位,用两个变量接收(利用top和pop函数)。
class Solution {
public:int lastStoneWeight(vector<int>& stones) {priority_queue<int> q;for(int i=0; i<stones.size(); i++){q.push(stones[i]);}while(q.size()>1){int x=q.top();q.pop();int y=q.top();q.pop();if(x != y) {q.push(x-y);}}if(q.empty()) {return 0;} else {return q.top();}}
};
分发饼干
455. 分发饼干https://leetcode.cn/problems/assign-cookies/
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i
,都有一个胃口值 g[i]
,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j
,都有一个尺寸 s[j]
。如果 s[j] >= g[i]
,我们可以将这个饼干 j
分配给孩子 i
,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。4
与上题思路相同
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {priority_queue<int> g_que,s_que;int res=0;for(int i=0;i<g.size();i++){g_que.push(g[i]);}for(int i=0;i<s.size();i++){s_que.push(s[i]);}while(!s_que.empty()&&!g_que.empty())//当同时存在时{if(g_que.top()<= s_que.top()){res++;g_que.pop();s_que.pop();}elseg_que.pop();}return res;}
};
面试题:最小k个数
面试题 17.14. 最小K个数https://leetcode.cn/problems/smallest-k-lcci/
提示
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4]
思路
创建一个队列(队列默认最大堆结构),将前k个始终维护成最大堆结构,k~arr.size()-1中每个元素始终与栈顶元素作比较,最终队列即为所求。
如果用最小堆的话,当数据量非常大时,时间复杂度太高了。
class Solution {
public:vector<int> smallestK(vector<int>& arr, int k) {if(k==0||arr.size()==0)return {};priority_queue<int> que;vector<int>res;for(int i=0;i<k;i++)que.push(arr[i]);for(int i=k;i<arr.size();i++){if(arr[i]<que.top()){que.pop();que.push(arr[i]);}}while(!que.empty()){res.push_back(que.top());que.pop();}return res;}
};
队列
周末舞会
1332:【例2-1】周末舞会 【题目描述】 假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。现要求写一个程序,模拟上述舞伴配对问题。 【输入】 第一行两队的人数; 第二行舞曲的数目。 【输出】 配对情况。 |
思路:
这段代码通过两个队列分别表示舞会上的男士和女士队伍,循环读取舞曲数目来模拟配对跳舞的过程。对于每首舞曲,从男女队列的队首分别取出一个人配对为舞伴,然后将这对舞伴放回队列的末尾以便参与下一轮配对,直至所有舞曲播放完毕。这样,通过队列的先进先出特性,实现了一个简单的舞伴轮换配对模拟。
#include<iostream>
#include<queue>//栈的头文件
using namespace std;int main()
{int m, n, k;cin >> m >> n >> k;queue<int>s1;queue<int>s2;for (int j = 1; j <= m; j++){s1.push(j);}for (int c = 1; c <= n; c++){s2.push(c);}for (int i = 1; i <= k; i++){cout << s1.front() << s2.front() << endl;int x = s1.front(), y = s2.front();s1.pop(); s2.pop();s1.push(x), s2.push(y);}return 0;
}
面试题--用两个队列实现栈
225. 用队列实现栈https://leetcode.cn/problems/implement-stack-using-queues/
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。
思路
这段代码通过两个队列`q1`和`q2`来模拟一个后入先出(LIFO)的栈结构。当新元素被加入(`push`操作)时,它直接进入`q1`。为了模拟栈的`pop`操作,代码将`q1`中的元素,除了最后一个加入的元素之外,都转移到`q2`中,这样`q1`中剩下的最后一个元素就是需要被`pop`的元素。在这个元素被移除后,`q2`的内容回到`q1`,实现了后入先出的逻辑。`top`操作简单地返回`q1`的最后一个元素,而`empty`操作检查`q1`是否为空,从而判断栈是否为空。
class MyStack {
public:queue<int>q1;queue<int>q2;void push(int x) {q1.push(x);}int pop() {while(q1.size()>1)//队列中只剩下一个元素{q2.push(q1.front());q1.pop();}int x=q1.front();//记录最后一个元素 即返回值q1.pop();q1=q2;while(!q2.empty())//清空q2{q2.pop();}return x;}int top() {return q1.back();}bool empty() {return q1.empty();}
};
面试题--用两个栈实现队列
232. 用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
void push(int x)
将元素 x 推到队列的末尾int pop()
从队列的开头移除并返回元素int peek()
返回队列开头的元素boolean empty()
如果队列为空,返回true
;否则,返回false
思路
这段代码使用两个栈`s1`和`s2`来实现一个队列。当元素被推入队列时,它被压入`s1`。要执行`pop`或`peek`操作时,如果`s2`为空,`s1`的所有元素逆序转移到`s2`中,使得`s1`的底部元素移动到`s2`的顶部,即队列的前端。这样,从`s2`中弹出或查看顶部元素就可以模拟队列的`pop`和`peek`操作。`empty`操作通过检查两个栈是否都为空来判断队列是否为空,实现了一个先入先出的队列行为。
class MyQueue {
public:
/*先将栈中元素除了最后一个取出*/
stack<int>s1;
stack<int>s2;void push(int x) {s1.push(x);}int pop() {if(s2.empty())//s2不为空的话直接删除,为空将s1中元素全部放入s2{while(!s1.empty()){s2.push(s1.top());s1.pop();}}int x=s2.top();s2.pop();return x;}int peek() {if(s2.empty())//s2不为空的话直接删除,为空将s1中元素全部放入s2{while(!s1.empty()){s2.push(s1.top());s1.pop();}}int x=s2.top();return x;}bool empty() {return s1.empty()&&s2.empty();//都为空才为空}
};