20. 有效的括号
大概算是比较典型的栈的题吧,以前上课的时候老师经常说正则表达式匹配啥的经常用到栈,但是我也没有仔细考虑过,这里来想一想
从左开始入栈,如果是左括号则入栈,如果是右括号则找栈顶的是否为对应左括号,如果不是直接false,否则弹出,直到弹栈弹完。如果最后字符串有剩余返回false,否则true。
class Solution20{
public:
/// @brief 给定一个只包括'(',')','{','}','[',']'的字符串s,判断字符串是否有效
/// 左括号必须有相同的右括号闭合
/// 左括号必须以正确的顺序闭合
/// 每个右括号都有一个对应的相同类型的左括号
/// @param s 只包括'(',')','{','}','[',']'
/// @return
bool isValid(string s){
stack<char> temp;
for(int i=0;i<s.size();i++){
if(s[i]=='('||s[i]=='{'||s[i]=='[')
{
temp.push(s[i]);
}
else{
if(temp.empty()){
return false;
}
if((s[i]==')'&&temp.top()=='(')||(s[i]=='}'&&temp.top()=='{')||(s[i]==']'&&temp.top()=='[')){
temp.pop();
}
else{
return false;
}
}
}
if(temp.empty()){
return true;
}
return false;
}
};
1047. 删除字符串中的所有相邻重复项
显然还是用栈,进进出出直到进完
之后看到长度最多20000,然后就改用了长度为20001的数组来实现(想偷懒不做赋值到string里的处理),然后它给了个100000长度的string,,,还是老老实实用stack吧
class Solution1047{
public:
/// @brief 给出由小写字母组成的字符串s,重复项删除操作会选择两个相邻且相同的字母
/// 并且删除他们
/// @param s 由小写字母组成的字符串
/// @return 删除后的字符串
string removeDuplicates(string s) {
stack<char> res;
for(int i=0;i<s.size();i++){
if(res.empty()){
res.push(s[i]);
continue;
}
if(res.top()==s[i]){
res.pop();
}
else{
res.push(s[i]);
}
}
s="";
while(!res.empty()){
s+=res.top();
res.pop();
}
reverse(s.begin(),s.end());
return s;
}
};
看到题解之后看到原来string能直接进行栈的操作啊,那省事了,再来!
class Solution1047{
public:
/// @brief 给出由小写字母组成的字符串s,重复项删除操作会选择两个相邻且相同的字母
/// 并且删除他们
/// @param s 由小写字母组成的字符串
/// @return 删除后的字符串
string removeDuplicates(string s) {
string res;
for(int i=0;i<s.size();i++){
if(res.empty()){
res.push_back(s[i]);
continue;
}
if(res.back()==s[i]){
res.pop_back();
}
else{
res.push_back(s[i]);
}
}
return res;
}
};
150. 逆波兰表达式求值
只有四个运算符加减乘除,
遇到运算符就进行栈顶两个元素的运算,ok思路有了,直接编码
需要两个操作:
1.判断是否为运算符
2.将整数字符串转换为整数
很容易解决
class Solution150{
private:
bool isNumber(string s){
if(s.size()!=1){
return true;
}
if(s[0]>='0'&&s[0]<='9'){
return true;
}
return false;
}
int convertNumber(string s){
int result=0;
int end=0;
if(s[0]=='-'){
end=1;
}
int weight=1;
for(int i=s.size()-1;i>=end;i--){
result+=weight*(s[i]-'0');
weight*=10;
}
if(end==1){
result*=-1;
}
return result;
}
public:
/// @brief
/// @param tokens 字符串数组 一个逆波兰表示法的算术表达式
/// @return token表达式的结果
int evalRPN(vector<string>& tokens) {
stack<int> number;
int temp1;
int temp2;
for(string s:tokens){
if(!isNumber(s)){
//说明是符号
temp1=number.top();
number.pop();
temp2=number.top();
number.pop();
if(s=="+"){
number.push(temp2+temp1);
}
else if(s=="-"){
number.push(temp2-temp1);
}
else if(s=="*"){
number.push(temp2*temp1);
}
else if(s=="/"){
number.push(temp2/temp1);
}
}
else{
//否则是数字
number.push(convertNumber(s));
}
}
return number.top();
}
};
思路一样,不过判断是不是符号我就有点想多了,然后数字转换那里我自己实现了一下。记住to这一类函数就行了。
今天做题很顺利,,虽然可能是比较简单。