前言:刷「栈和队列」高频面试题。
详细介绍参考 06 讲: 栈和队列简析 (点击链接直达)
栈类比羽毛球筒,具有后进先出的性质,只在 栈顶 进行相关操作。
栈顶下标初始化为 0 表示栈空。
队列类比排队买票,具有先进先出的性质,在 队尾插入 元素,在 队头弹出 元素。
队头下标为 0,队尾下标为 -1,表示队列为空。
原题链接:有效的括号(点击链接直达)
class Solution {
public:bool isValid(string s) {stack stack; //(1)for (char c : s) //(2){if (c == '(' || c == '{' || c == '[') stack.push(c); //(3)else {if (stack.size() && abs(c - stack.top()) <= 2) stack.pop(); //(4)else return false; //(5)}}return stack.empty(); //(6)}
};
<= 2);> 2 说明左右括号不匹配,不合法;true,否则说明左括号多了,返回 false;O(n)O(n)O(n)
原题链接:最小栈(点击链接直达)
i 个,维护前 i 个数的最小值),全局最小值就是新栈的栈顶元素;min 然后插入新栈。原栈弹出一个数时,新栈同时也弹出一个数;class MinStack {
public:vector preMin; //(1)vector stk; //(2)MinStack() {}void push(int val) { preMin.push_back(stk.empty() ? val : min(val, preMin.back())); //(3)stk.push_back(val); //(4)}void pop() {preMin.pop_back(); //(5)stk.pop_back(); //(6)} int top() {return stk.back(); //(7)}int getMin() {return preMin.back(); //(8)}
};
preMin 为新栈,用来维护前缀最小值;stk 为原栈,用来维护原栈的一些信息;O(1)O(1)O(1)
原题链接:用队列实现栈(点击链接直达)
a 中压入一个元素,队列和栈的实现相同。例如,压入元素 4 ->[4 3 2 1];4 弹出,而按队列的弹出方式应该将 1 弹出。如果要通过队列实现栈的弹出,应该先将 4 找到,然后将 4 弹出。实现方式是先将 1 2 3 先弹出,此时,需要一个缓存队列 b 存储 1 2 3,然后将 4 弹出。弹出之后,再将 1 2 3 放回到队列 a 中。4 找到,然后返回。注意:返回之后,需要将 4 弹出,然后压入队列 b 中,然后再将队列 b 中的 1 2 3 4 放回队列 a 中,目的是为了保证数据原有的顺序;a 是否为空;class MyStack {
public:queue a; // 队列queue b; // 缓存队列MyStack() {}void push(int x) {a.push(x);}int pop() {while (a.size() > 1) b.push(a.front()), a.pop();int t = a.front();a.pop();while (b.size()) a.push(b.front()), b.pop();return t;}int top() {while (a.size() > 1) b.push(a.front()), a.pop();int t = a.front();a.pop();b.push(t);while (b.size()) a.push(b.front()), b.pop();return t;}bool empty() {return a.empty();}
};
原题链接:用栈实现队列(点击链接直达)
class MyQueue {
public:stack a, b;MyQueue() {}void push(int x) {a.push(x);}int pop() {while (a.size() > 1) b.push(a.top()), a.pop();auto t = a.top();a.pop();while (b.size()) a.push(b.top()), b.pop();return t;}int peek() {while (a.size() > 1) b.push(a.top()), a.pop();auto t = a.top();while (b.size()) a.push(b.top()), b.pop();return t;}bool empty() {return a.empty();}
};
原题链接:逆波兰表达式(点击链接直达)
class Solution {
public:int evalRPN(vector& tokens) {stack stk;for (auto c : tokens) {if (c == "+" || c == "-" || c == "*" || c == "/") { // 运算符int b = stk.top(); stk.pop(); // 先弹出的是 bint a = stk.top(); stk.pop(); // 后弹出的是 aif (c == "+") a = a + b;else if (c == "-") a = a - b;else if (c == "*") a = a * b;else a = a / b;stk.push(a); }else { // 数stk.push(stoi(c));}}return stk.top();}
};
上一篇:单例的几种写法