20. 有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
先分析字符串无效的情况有哪些:
- 第一种情况,字符串里左方向的括号多余;
- 括号的类型不匹配;
- 第三种情况,字符串里右方向的括号多余;
此外由于有效的字符串左右括号匹配,所以对于字符串大小为奇数的可以直接认为无效。
遍历到左括号时,入栈对应的右括号,可以方便在之后对于右括号的比较直接进行。
class Solution {
public:
bool isValid(string s) {
if(s.size() % 2 != 0) //剪枝
return false;
stack<char> t;
for(int i = 0; i < s.size(); i++){
if(s[i] == '(')
t.push(')');
else if(s[i] == '{')
t.push('}');
else if(s[i] == '[')
t.push(']');
else if(t.empty() || t.top() != s[i]) //右方向括号多余或括号类型不匹配
return false;
else t.pop();
}
return t.empty();// 3 如果左方向括号多余,栈不为空,返回false
}
};
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S
,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
定义一个栈存放遍历过的元素,当遍历当前的这个元素的时候,去栈里查看是否遍历过相同数值的相邻元素。相等栈顶元素出栈,不等就放入栈中。
class Solution {
public:
string removeDuplicates(string s) {
string t;
for( auto c:s){
if(t.empty() || t.back() != c)
t.push_back(c);
else
t.pop_back();
}
return t;
}
};
150. 逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +
、-
、*
、/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
从左到右遍历表达式的每个符号和数字,,遇到数字就进栈,遇到符号就将栈顶的两个数字出栈进行运算,运算结果进栈,直到最后获得结果。
栈中元素用long,不然用例["-128","-128","*","-128","*","-128","*","8","*","-1","*"]会溢出。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long int> t;
for(int i = 0; i < tokens.size(); i++){
if(tokens[i] == "+" || tokens[i] == "-"|| tokens[i] == "*" || tokens[i] == "/"){
long int num_1 = t.top();
t.pop();
long int num_2 = t.top();
t.pop();
if(tokens[i] == "+")
t.push(num_1+num_2);
if(tokens[i] == "-")
t.push(num_2-num_1);
if(tokens[i] == "*")
t.push(num_2*num_1);
if(tokens[i] == "/")
t.push(num_2/num_1);
}
else
t.push(stoi(tokens[i])); //将字符串转换为十进制
}
int res = t.top();
t.pop();
return res;
}
};