20. 有效的括号
- 做题之前要考虑好括号不匹配有哪几种情况。
- 当遇到左括号时将对应的右括号入栈,这样在遇到右括号时就可以直接匹配而不做其他处理。
三种不匹配的情况:
-
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
-
第二种情况,括号没有多余,但是 括号的类型没有匹配上。
-
第三种情况,字符串里右方向的括号多余了,所以不匹配。
class Solution {
public:
bool isValid(string s) {
stack<char> kuo;
for(int i=0;i<s.size();i++){
if (s[i]=='(') kuo.push(')');
else if(s[i]=='[') kuo.push(']');
else if(s[i]=='{') kuo.push('}'); //遇到左括号时把对应的右括号入栈
else if(kuo.empty()||kuo.top()!=s[i]) return false; //如果没有遍历完栈就空了或字符不匹配
else kuo.pop(); //如果匹配就弹出元素
}
return kuo.empty(); //栈空说明括号匹配返回true,不空说明不匹配返回false
}
};
1047. 删除字符串中的所有相邻重复项
做过上道题这题就非常简单了,遇到把s挨个入栈,当碰到相同元素时就出栈。
需要注意的是最后res存放结果时由于栈先进后出,所以要反转一下res字符串。
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for (int i = 0; i < s.size(); ++i) {
if (st.empty()||s[i]!=st.top()) st.push(s[i]); //栈为空或者元素不相等则入栈
else st.pop(); //相等则出栈
}
string res=""; //res用来存放结果,将栈中元素放入res中
while(!st.empty()){
res+=st.top();
st.pop();
}
reverse(res.begin(),res.end()); //由于栈是先进后出所以要反转一下字符串
return res;
}
};
150. 逆波兰表达式求值
这题主要是不知道什么是逆波兰表达式,其实逆波兰表达式相当于是二叉树中的后序遍历。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。
-
适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
这么一看好像和上面的题也没有什么区别了,当遇到运算符的时候从栈内取出两个元素进行运算,注意除法和减法要后取的值在前。遇到数字就存到栈内。最后用res收集栈中最后的数返回。
这个题比较坑的是要力扣修改了后台测试数据,需要用longlong。
1、stol()
此函数将在函数调用中作为参数提供的字符串转换为long int。它解析str并将其内容解释为指定基数的整数,并将其作为long int类型的值返回。
2、stoll()
此函数将在函数调用中作为参数提供的字符串转换为long long int。它解析str并将其内容解释为指定基数的整数,并将其作为long
long int类型的值返回。
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(num1+num2);
if (tokens[i] == "-" ) st.push(num2-num1);
if (tokens[i] == "*" ) st.push(num1*num2);
if (tokens[i] == "/" ) st.push(num2/num1);
} else{
st.push(stoll(tokens[i]));
}
}
int res=st.top();
st.pop();
return res;
}
};