栈与队列
- 栈与队列理论基础
- 232.用栈实现队列
- 225.用队列实现栈
- 20.有效的括号
- 1047.删除字符串中的所有相邻重复项
- 150.逆波兰表达式求值
- 239.滑动窗口最大值
- 347.前k个高频元素
- 栈与队列总结
栈与队列理论基础
栈与队列理论基础
232.用栈实现队列
力扣题目链接
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
int res = stOut.top();
stOut.pop();
return res;
}
int peek() {
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
int res = stOut.top();
return res;
}
bool empty() {
if(stOut.empty() && stIn.empty()){
return true;
}
else{
return false;
}
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
225.用队列实现栈
力扣题目链接
C++deque的基本操作:
总体思路:deq2当deq1的备份使用,每次pop(),或者top(),都把deq1中的元素都移到deq2中,只给deq1留下一个元素,pop()或者top()结束后再把deq2中的元素移回来。
class MyStack {
public:
deque<int> deq1;
deque<int> deq2;
MyStack() {
}
void push(int x) {
deq1.push_back(x);
}
int pop() {
if(!deq1.empty()){
while(deq1.size()>1){
deq2.push_back(deq1.front());
deq1.pop_front();
}
}
int res = deq1.front();
deq1.pop_front();
while(!deq2.empty()){
deq1.push_back(deq2.front());
deq2.pop_front();
}
return res;
}
int top() {
if(!deq1.empty()){
while(deq1.size()>1){
deq2.push_back(deq1.front());
deq1.pop_front();
}
}
int res = deq1.front();
deq2.push_back(res);
deq1.pop_front();
while(!deq2.empty()){
deq1.push_back(deq2.front());
deq2.pop_front();
}
return res;
}
bool empty() {
return deq1.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
20.有效的括号
力扣题目链接
class Solution {
public:
bool isValid(string s) {
stack<char> st;
for (auto str : s)
{
switch (str) {
case '(':
case '{':
case '[':
if (str == '(') st.push(')');
else if (str == '{') st.push('}');
else st.push(']');
break;
case ')':
case '}':
case ']':
if (st.empty()) {
return false;
}
if (str != st.top()) {
return false;
}
else {
st.pop();
break;
}
}
}
if (st.empty()) return true;
else return false;
}
};
1047.删除字符串中的所有相邻重复项
力扣题目链接
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
string res;
for(auto str:s){
if(st.empty()){
st.push(str);
}
else{
if(str==st.top()){
st.pop();
}
else{
st.push(str);
}
}
}
if(st.empty()){
return "";
}
else{
while(!st.empty()){
res+=st.top();
st.pop();
}
reverse(res.begin(),res.end());
return res;
}
}
};
150.逆波兰表达式求值
力扣题目链接
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
for(int i =0;i<tokens.size();i++){
if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/"){
long long num1 = st.top();
st.pop();
long long num2 = st.top();
st.pop();
if(tokens[i]=="+") st.push(num2+num1);
else if(tokens[i]=="-") st.push(num2-num1);
else if(tokens[i]=="*") st.push(num2*num1);
else st.push(num2/num1);
}
else{
st.push(stoll(tokens[i]));
}
}
int res = st.top();
st.pop();
return res;
}
};
239.滑动窗口最大值
力扣题目链接
单调队列≠对窗口里的元素进行实时排序
单调队列设计思想:
- pop(val):如果窗口元素val的值等于队列出口的元素的值,则弹出队列出口的元素的值,否则不进行任何操作
- push(val):如果窗口元素val的值大于队列入口元素的值,则弹出队列入口的元素的值,一直到窗口元素的值小于等于队列入口的元素。
- front():返回队列出口的元素的值。
class Solution {
private:
class Myqueue {
public:
deque<int> deq;
void pop(int val) {
if (!deq.empty() && deq.front() == val) {
deq.pop_front();
}
}
void push(int val) {
while (!deq.empty() && val > deq.back()) {
deq.pop_back();
}
deq.push_back(val);
}
int front() {
return deq.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
Myqueue mq;
vector<int> res;
for (int i = 0; i < k; i++) {
mq.push(nums[i]);
}
res.push_back(mq.front());
for (int i = k; i < nums.size(); i++)
{
mq.pop(nums[i-k]);
mq.push(nums[i]);
res.push_back(mq.front());
}
return res;
}
};
347.前k个高频元素
力扣题目链接
C++priority_queue的使用方法
优先级队列:priority_queue容器适配器模拟的也是队列这种存储结构,即使用此容器适配器存储元素只能从一端进,从另一端出,且每次只能访问队列中的队头元素,和队尾元素。但优先级队列遵循的原则不是先入先出,而是先入优先级大的出。
- 大顶堆:最大的元素在堆顶
- 大顶堆的排序规则:bool operator()(const T &_lhs,const T &_rhs) const{ return _lhs<_rhs;}
- 把大元素放到右面也就是堆顶,也就是队列要pop的地方。
- 小顶堆:最小的元素在堆顶
- 小顶堆的排序规则:bool operator()(const T &_lhs,const T &_rhs) const{ return _lhs>_rhs;}
- 把小元素放到右面也就是堆顶,也就是队列要pop的地方。
class Solution {
public:
class cmp {
public:
bool operator()(pair<int, int> lhs, pair<int, int>rhs) {
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> umap;
vector<int> res;
for (int i = 0; i < nums.size(); i++) {
umap[nums[i]]++;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> prq;
for (auto iter = umap.begin(); iter != umap.end(); iter++)
{
int a = iter->first;
int b = iter->second;
prq.push({a,b}); // prq.push(pair<int,int>(a,b)) or prq.push(*iter)
if (prq.size() > k)
{
prq.pop();
}
}
while (!prq.empty()) {
auto ans = prq.top();
res.push_back(ans.first);
prq.pop();
}
return res;
}
};
栈与队列总结
栈与队列总结