由于栈(队列)底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能),所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。
C++ STL stack
push()
:将元素压入栈顶。pop()
:将栈顶元素弹出。top()
:访问栈顶元素。empty()
:检查栈是否为空。size()
:返回栈中元素的数量。
C++ STL queue
push()
:将元素加入队列的尾部。pop()
:将队列的头部元素移除。front()
:访问队列头部元素。back()
:访问队列尾部元素。empty()
:检查队列是否为空。size()
:返回队列中元素的数量。
232.用栈实现队列
知道两个栈尾尾相接就可以实现队列了,但实现起来还是卡了一下。
class MyQueue {
public:stack<int> fronts;stack<int> tails;MyQueue() {}void push(int x) {tails.push(x);}int pop() {if(fronts.empty()){ //注意这里是fronts为空才可以操作,否则顺序就乱了while(!tails.empty()){fronts.push(tails.top());tails.pop();}}int res=fronts.top();fronts.pop();return res;}int peek() {if(fronts.empty()){while(!tails.empty()){fronts.push(tails.top());tails.pop();}}return fronts.top();}bool empty() {return fronts.empty()&&tails.empty();}
};
225. 用队列实现栈
队列FIFO,所以即使出队列再入队列顺序也不会改变。而两个栈先弹出再放入顺序就会反转。
class MyStack {
public:queue<int> que;MyStack() {}void push(int x) {que.push(x);}int pop() {int size = que.size();size--;while (size--) {que.push(que.front());que.pop();}int result = que.front();que.pop();return result;}int top(){int size = que.size();size--;while (size--){que.push(que.front());que.pop();}int result = que.front(); que.push(que.front()); que.pop();return result;}bool empty() {return que.empty();}
};
20. 有效的括号
一开始面试写了这个题,用的vector没有用stack,换成stack来写一遍
class Solution {
public:bool isValid(string s) {stack<char> st;int len=s.size();for(char c:s){if(c=='('||c=='['||c=='{'){st.push(c);}else if(c==')'){if(!st.empty()&&st.top()=='(') st.pop();else return false;}else if(c==']'){if(!st.empty()&&st.top()=='[') st.pop();else return false;}else if(c=='}'){if(!st.empty()&&st.top()=='{') st.pop();else return false;}}if(!st.empty()) return false;return true;}
};
但是这样写if else太多了,很不美观,看下标准答案:
class Solution {
public:bool isValid(string s) {if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求stack<char> st;for (char c:s) {if (c == '(') st.push(')');else if (c == '{') st.push('}');else if (c == '[') st.push(']'); //让左括号入栈//如果在过程中st空了则也是错误else if (st.empty() || st.top() != c) return false;else st.pop();}return st.empty();}
};
1047. 删除字符串中的所有相邻重复项
和括号匹配一样,不过是将栈中剩余的内容再输出而已。还要注意的一个小点是由于栈是FIFO,所以最后res字符串要reverse一下。
class Solution {
public:string removeDuplicates(string s) {stack<char> st;for(char c:s){if(!st.empty()&&c==st.top()) st.pop();else st.push(c);}string res="";while(!st.empty()){res+=st.top();st.pop();}reverse(res.begin(),res.end());return res;}
};