day11 | 第五章 栈与队列part02
20. 有效的括号
这个题目并没有优先级的考虑,只需要匹配好括号就可以了。左括号是怎么来的,那么右括号就是怎么匹配上的,感觉这里解释起来就很抽象,用栈就很直观的解决了,但是不知道该怎么解释如何想到的?左括号是进栈,右括号是对应着消除,退栈。
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for(auto& c : s) {
switch(c) {
case '(': stk.push(c);
break;
case '[': stk.push(c);
break;
case '{': stk.push(c);
break;
case ')': {
if(stk.empty() || stk.top() != '(') {
return false;
}
else {
stk.pop();
}
}
break;
case ']': {
if(stk.empty() || stk.top() != '[') {
return false;
}
else {
stk.pop();
}
}
break;
case '}':
{
if(stk.empty() || stk.top() != '{') {
return false;
}
else {
stk.pop();
}
}
}
}
return stk.empty();
}
};
1047. 删除字符串中的所有相邻重复项
思考这样一个问题,如果从左往右去遍历整个字符串,依次将字符入栈,则当前字符和栈顶的关系就是当前字符和它前面相邻字符的关系,也就是题目所考虑的相邻字符的关系。
这题使用数组模拟栈,效率更高
class Solution {
public:
string removeDuplicates(string s) {
const int N = s.size();
char stk[N];
int tt = -1;
for(auto& c : s) {
if(tt == -1) {
stk[++tt] = c;
}
else {
auto top = stk[tt];
if(top == c) {
--tt;
}
else {
stk[++tt] = c;
}
}
}
string ret = "";
while(tt != -1) {
ret += stk[tt--];
}
reverse(ret.begin(), ret.end());
return ret;
}
};
150. 逆波兰表达式求值
经典的栈使用的题目,需要注意的是,依次弹出两个操作数a, b是将a放在后面,比如我们现在遇到了运算符 /,现在需要弹出两个操作数a, b,则我们需要运算是b/a
另外这道题给的范围数字可以到200,长度到\(10^4\)如果全是乘法那就是\(200^{10000}\)是会爆int的,所以我们的结果和运算过程要用long算,整体思路就是遇到数字直接进栈,遇到运算符就弹出两个数字运算,算完了又弹进去。
class Solution {
public:
inline bool judge(string& s) {
return s != "/" && s != "*"&& s != "-"&& s != "+";
}
int evalRPN(vector<string>& tokens) {
stack<long> stk;
for(auto& token:tokens) {
if(judge(token)) {
stk.push(atoi(token.c_str()));
}
else {
long a = stk.top();
stk.pop();
long b = stk.top();
stk.pop();
switch(token[0]) {
case '+': stk.push(b + a);break;
case '-': stk.push(b - a);break;
case '*': stk.push(b * a);break;
case '/': stk.push(b / a);break;
}
}
}
return stk.top();
}
};

浙公网安备 33010602011771号