9.栈与队列Ⅱ
20有效的括号
题目描述
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()"
输出:true
解题思路
遍历字符串中的字符,将当前字符与栈顶元素做判断,如果是匹配括号,那么执行弹出栈顶元素操作,如果不匹配,就把当前字符串元素压入栈中。遍历结束时,如栈不为空,则说明不匹配,若为空,则说明所有元素都匹配上了。
注意,在访问栈顶之前要先判断栈不为空才能访问。
代码实现
class Solution {
public:
bool isValid(string s) {
if(s.size()%2==1)//若括号个数为奇数,则说明不匹配
{
return false;
}
stack<char>st;
for(int i=0;i<s.size();i++)
{
if(!st.empty()&&((s[i]==']'&&st.top()=='[')||(s[i]==')'&&st.top()=='(')||(s[i]=='}'&&st.top()=='{')))
{
cout<<i<<endl;
st.pop();
cout<<"count"<<endl;
}
else
{
st.push(s[i]);
}
}
if (!st.empty())
{
return false;
}
return true;
}
};
总结
对于栈来说,若想访问栈顶元素,需要先判断栈不为空,不为空才能访问,否则会报错。
1047删除字符串中的所有相邻重复项
题目描述
给出由小写字母组成的字符串 S
,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
解题思路
删除相邻重复元素,思路跟上一题括号匹配相同,相邻相同字符即为匹配括号。利用栈来存储元素,判断当前字符与栈顶元素是否相同,相同就弹出,不同就入栈。最后栈里剩余的元素就是有效字符串。然后将栈的元素出栈,逆序写入字符串再返回。
代码实现
class Solution {
public:
string removeDuplicates(string s) {
stack<char>st;
for(int i=0;i<s.size();i++)
{
if(!st.empty()&&(st.top()==s[i]))
{
st.pop();//弹出栈顶元素
}
else
{
st.push(s[i]);
//cout<<i<<endl;
}
}
//将栈中的元素写入字符串
s.resize(st.size());
for(int j=s.size()-1;j>=0;j--)
{
s[j]=st.top();
st.pop();
}
return s;
}
};
总结
没有一遍ac,错误在于:
if判断相等写成了一个等号,size后面漏写了小括号。
注意代码编写的严谨性,争取一次ac。
150逆波兰表达式求值
题目描述
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +
、-
、*
、/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
注意 两个整数之间的除法只保留整数部分。
可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
解题思路
与前一题思路一样,将token中的字符串转换为数字,往栈里面放。遇到数字就直接放入栈里面,遇到运算符就从栈顶取出两个元素,进行运算,将运算的结果放入栈顶。
代码实现
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long>st;
long long a,b,res;
//遍历tokens中的元素
for(int i=0;i<tokens.size();i++)
{
//如果是运算符
if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
{
//从栈顶取两个元素
b=st.top();//因为表达式有效,因而不用再判断栈是否为空
st.pop();
a=st.top();
st.pop();
//对运算符进行求解
if(tokens[i]=="+")
{
res=a+b;
}
else if(tokens[i]=="-")
{
res=a-b;
}
else if(tokens[i]=="*")
{
res=a*b;
}
else
{
res=a/b;
}
st.push(res);//将计算得到的结果入栈
}
else//如果是数字
{
//字符串转数字调用函数stoi(string a)
st.push(stoi(tokens[i]));
//cout<<"栈顶元素:"<<stoi(tokens[i])<<endl;
}
}
return st.top();//栈顶剩余元素即为表达式值
}
};
总结
由于测试案例中有极大数存在,因此存储的栈和运算的数字要定义成long long数据。
将字符串转换为数字可以用stoi(string a)函数实现,返回的就是数值。