今天是刷题的第11天,昨天的题目相对轻松,即用队列实现栈,用栈实现队列,今天就是栈和队列的第二部分,主要在于应用,如下所示:
今日任务:
- 有效的括号
- 删除字符串中的所有相邻重复项;
- 逆波兰表达式求值;
题目一:20. 有效的括号
Leetcode 题目:【20.有效的括号】
参考:【代码随想录之20. 有效的括号】
思路:本题一开始觉着错误情况太多,有点复杂,但是经过Carl的视频讲解,明确了再多的情况也不外乎3种出错的场景:
(1)左方向的括号多余;
(2)有方向的括号多余;
(3)左右方向的括号没有匹配上;
class Solution {
public:
bool isValid(string s) {
if(s.size() % 2 != 0){return false;}
stack<char> st; // 新建栈
for(int i = 0; i<s.size(); i++){
if(s[i] == '[') st.push(']');
else if(s[i] == '{') st.push('}');
else if(s[i] == '(') st.push(')');
// 遇到了右括号类型
else{
if(st.empty() || s[i] != st.top()) {return false;}
else{
st.pop();
}
}
}
return st.empty();
}
};
易出错的点:最后返回的是st.empty(),而不是true,因为无法满足“((”的情况,如果是上面的情况,那么栈里面一定不为空,但按照逻辑而言,最后栈应该要清空。
题目二:1047.删除字符串中的所有相邻项
Leetcode 题目:【1047.删除字符串中的所有相邻项】
解析参考:【代码随想录之删除字符串中的所有相邻项】,类似消消乐
消消乐这种的题目用栈这种数据结构非常适合,
自己的代码思路:(与卡哥的思路相同)
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
string new_s;
st.push(s[0]);
for(int i = 1; i<s.size(); i++){
if(st.empty()) {
st.push(s[i]);
}else{
if(s[i] == st.top())
{
st.pop();
}else{
st.push(s[i]);
}
}
}
while(!st.empty()){
char new_letter = st.top();
cout << "char: " << new_letter << endl;
st.pop();
new_s +=new_letter;
}
reverse(new_s.begin(),new_s.end());
return new_s;
}
};
更简洁的代码,直接拿字符串当栈是用,建立一个新的字符串
关于字符串常用的方法如下:
string a="abcd";
1.获取字符串最后一个字符
auto b=a.back(); //结果为 b='d';
2.修改字符串最后一个字符
a.back()='!'; //结果为 a="abc!";
3.获取字符串第一个字符
auto b=a.front(); //结果为 b='a';
4.修改字符串第一个字符
a.front()='!'; //结果为 a="!bcd";
直接用字符串string容器秒了。
class Solution {
public:
string removeDuplicates(string s) {
string new_s;
for(int i = 0; i<s.size(); i++){
if(new_s.empty() || new_s.back() != s[i]){
new_s.push_back(s[i]);
}else{
new_s.pop_back();
}
}
return new_s;
}
};
注意:pop_back()表示只删除最后一个元素,也可采用erase删除 str.erase(str.end() -1);
题目三:150. 逆波兰表达式求值
Leetcode题目:【150. 逆波兰表达式求值】
参考:【代码随想录之逆波兰表达式求值】
逆波兰表达式指一种后缀表达式,它是非常方便计算机进行计算的(计算机可以顺序去处理表达式,不需要加括号)。
二叉树的遍历方式为左、右、中,后缀表达式就是二叉树的一种后序遍历方法。
一般都是用栈来计算后缀表达式,后缀表达式的结果就是栈里面留下来的元素。
栈比较擅长相邻字符的消除操作的问题。
此题的逻辑比较简单,就是在写法上,注意stoll,将字符串转为long long类型的数据
class Solution {
public:
int evalRPN(vector<string>& tokens) {
long long result;
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] == "+") result = num1 + num2;
else if(tokens[i] == "-") result = num2 - num1;
else if(tokens[i] == "*") result = num2 * num1;
else if(tokens[i] == "/") result = num2 / num1;
st.push(result);
}else{
st.push(stoll(tokens[i]));
}
}
return st.top();
}
};