第五章 栈与队列part02
1.LeetCode. 有效的括号
1.1题目链接:20. 有效的括号
1.2思路:先后要知道不符合的字符串情况有三种,分别是左括号多余,右括号多余,左右括号不匹配;该题目利用栈的特点进行遍历元素存放在栈中,但是是按照遍历到左括号把相应的右括号存放在栈中,然后如果遍历到右括号让其去栈中的元素比较符合就弹出,不符合 说明存在无效括号。
1.3附加代码如下所示:
class Solution {
public:
bool isValid(string s) {
stack<char>stak;
int size=s.size();
//如果字符串个数不是偶数说明肯定有多余的括号
if(size%2!=0)
{
return false;
}
for(int i=0;i<size;i++)
{
//遍历元素左括号存放在栈中
if(s[i]=='(')
{
stak.push(')');
}
else if(s[i]=='[')
{
stak.push(']');
}
else if(s[i]=='{')
{
stak.push('}');
}
//字符串没遍历完栈已经空了说明右括号多了
else if(stak.empty())
{
return false;
}
//说明有左右括号不匹配
else if(s[i]!=stak.top())
{
return false;
}
else
{
stak.pop();
}
}
//全部字符串遍历结束栈中还有剩余说明有多余的括号
return stak.empty();
}
};
2.LeetCode. 删除字符串中的所有相邻重复项
2.1题目链接:1047. 删除字符串中的所有相邻重复项
2.2思路:本题也是采用栈作为容器,先遍历字符串中元素存放在栈中,一个一个遍历,遇到和之前相同的元素就把之前栈中的元素给pop出,直到遍历完所有字符串元素。卡哥视频讲解采用字符串模拟栈,这样才返回的时候就不需要把栈中的元素pop出来了。
2.3附加代码如下所示:
(1)直接用栈当容器
class Solution{
public:
string removeDuplicates(string s)
{
int size=s.size();
stack<char>stak;
for(int i=0;i<size;i++)
{
//栈如果是空的或者遍历到的元素和栈顶元素不相同就入栈
if(stak.empty()||s[i]!=stak.top())
{
stak.push(s[i]);
}
else
{
stak.pop();
}
}
string s1="";//顶一个空字符串用来存放遍历结束后栈中剩余的元素
while(!stak.empty())
{
s1+=stak.top();
stak.pop();
}
reverse(s1.begin(),s1.end());//因为从栈中出来的元素是按照先进后出顺序排列的,所有最后要反转一下
return s1;
}
};
(2)采用字符串模拟栈功能
//采用字符串模拟栈
class Solution{
public:
string removeDuplicates(string s)
{
string s1;
for(char t:s)
{
if(s1.empty()||t!=s1.back())
{
s1.push_back(t);
}
else
{
s1.pop_back();
}
}
return s1;
}
};
3.LeetCode.逆波兰表达式求值
3.1题目链接:150. 逆波兰表达式求值
3.2思路逆波兰表达式就是实现左右中形式的二叉树模型又称后缀形式,按照这种形式进行运算,这种形式是计算机能够顺序执行的一种,也是采用半栈当容器,把遍历到的元素放到容器中,遇到运算符号就进行运算然后把结果再放到容器中,不断进行循环操作。
3.3附加代码如下所示:
本题犯的错误不是大毛病二是把string类型的字符串和char类型的字符搞混了
//采用栈当容器,依次遍历元素遇到运算符号就进行元素然后再把结果当如到栈中
//本题犯的错误不是大毛病二是把string类型的字符串和char类型的字符搞混了
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int>stack;
int size=tokens.size();
for(int i=0;i<size;i++)
{
if(tokens[i]!="+"&&tokens[i]!="-"&&tokens[i]!="*"&&tokens[i]!="/")//这里比较的是字符串string,不是字符char类型的不能这样写tokens[i]!='+'&&tokens[i]!='-'&&tokens[i]!='*'&&tokens[i]!='/'
{
//C++中字符串转化为整型的函数stoi,stol,stoll;C语言中是atoi,atol,strtol,strtoul
stack.push(stoll(tokens[i]));//这里要将字符串形式的数字转化为整形的数值,因为我们要计算的就是数值大小,而不是字符
}
else
{
//将栈中前两个元素给pop出来进行运算
int nums1=stack.top();stack.pop();
int nums2=stack.top();stack.pop();
//根据遍历到的运算符号选择运算法则再把运算结果放入到栈中
// 在进行四则运算时候要注意谁在前谁在后
if(tokens[i]=="+")
{
stack.push(nums1+nums2);
}
else if(tokens[i]=="-")
{
stack.push(nums2-nums1);
}
else if(tokens[i]=="*")
{
stack.push(nums2*nums1);
}
else if(tokens[i]=="/")
{
stack.push(nums2/nums1);
}
}
}
return stack.top();
}
};