代码随想day11 | 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

 20. 有效的括号 

        这道题目是栈的典型应用,总体思路是左括号压栈,右括号判断是否匹配。但是我在写代码时考虑不周到,忽略了不匹配的一种情况可能是栈里面为空,增加条件后,详细代码如下:

class Solution {
public:
    bool isValid(string s) {
        unordered_map<char,char> map;
        map[')'] = '(';
        map[']'] = '[';
        map['}'] = '{';
        stack<char> sta;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='('||s[i]=='['||s[i]=='{') sta.push(s[i]);
            else
            {
                if(sta.empty()||map[s[i]]!=sta.top()) return false;
                sta.pop();
            }
        }
        return sta.empty();

    }
};

        这道题目也可以不借助哈希表,一个巧妙的思路是遇到左括号的时候直接压入对应的右括号,这样遇到右括号的时候只需要直接对比相等即可,代码如下:

class Solution {
public:
    bool isValid(string s) {
        if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
        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(']');
            // 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
            // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
            else if (st.empty() || st.top() != s[i]) return false;
            else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
        }
        // 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
        return st.empty();
    }
};

 1047. 删除字符串中的所有相邻重复项 

        这道题目同样也是使用栈来解决,遇到相同的就pop,不相等就push,然后再把栈里的都pop出来进行反转即可,代码如下:

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> sta;
        string res;
        for(int i=0;i<s.size();i++)
        {
            if(!sta.empty()&& sta.top()==s[i]) sta.pop();
            else sta.push(s[i]);
        }
        while(!sta.empty())
        {
            res+=(sta.top());
            sta.pop();
        }
        reverse(res.begin(),res.end());
        return res;

    }
};

遗留问题:为什么在获得res时候,不能使用append()函数呢???

 150. 逆波兰表达式求值 

        这道题目有两个步骤:首先用一个函数把字符转换成数字,接着用栈来保存数字,遇到操作符进行对应计算即可,要注意是第二个pop出来的数是被除数or被乘数。自己实现的详细代码如下:(不简洁)

class Solution {
public:
    int stringtoint(string s)
    {
        int res=0;
        int n=1;
        for(int i =s.size()-1;i>=0;i--)
        {
            if(s[i]=='+') break;
            else if(s[i]=='-') res = -res;
            else
            {
                res+=(n*(s[i]-'0'));
                n*=10;
            }
        }
        return res;
    }
    int evalRPN(vector<string>& tokens) {
        stack<int> sta;
        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i].size()==1&&(tokens[i]=="+"))
            {
                long tmp1 = sta.top(); sta.pop();
                long tmp2 = sta.top();sta.pop();
                tmp2+=tmp1;
                sta.push(tmp2);
            }
            else if(tokens[i].size()==1&&(tokens[i]=="-"))
            {
                int tmp1 = sta.top(); sta.pop();
                int tmp2 = sta.top();sta.pop();
                tmp2-=tmp1;
                sta.push(tmp2);                
            }
            else if(tokens[i].size()==1&&(tokens[i]=="*"))
            {
                long tmp1 = sta.top(); sta.pop();
                long tmp2 = sta.top();sta.pop();
                tmp2*=tmp1;
                sta.push(tmp2);                
            }
            else if(tokens[i].size()==1&&(tokens[i]=="/"))
            {
                int tmp1 = sta.top(); sta.pop();
                int tmp2 = sta.top();sta.pop();
                tmp2/=tmp1;
                sta.push(tmp2);                
            }
            else
            {
                int tmp = stringtoint(tokens[i]);
                sta.push(tmp);
            }
        }
        return sta.top();
        
    }
};

看代码随想录有两点可以精简的地方:

1. 字符转数字有库函数

函数:
int atoi(const char *str):        //字符串转int 
long atol(const cahr *str):        //字符串转long
long long atoll(const cahr *str):        //字符串转long long
double atof(const char *str):         //字符串转double

2. 每次遇到运算符时的对于栈的压栈和出战操作是一样的 ,不需要重复写四遍,只需要把对应的运算分开写就行,精简后代码如下:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> sta;
        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
            {

                int tmp1 = sta.top(); sta.pop();  //取数1
                int tmp2 = sta.top();sta.pop();   //取数2
                if(tokens[i]=="+") tmp2+=tmp1;
                else if((tokens[i]=="-")) tmp2-=tmp1;
                else if(tokens[i]=="*") tmp2*=tmp1;
                else if(tokens[i]=="/") tmp2/=tmp1;
                sta.push(tmp2);  //压入计算完的数              

            }
            else
            {
                int tmp = stoi(tokens[i]);
                sta.push(tmp);
            }
        }
        return sta.top();
        
    }
};

心得:关于栈的经典应用题目,需要熟悉掌握,string的一些api还不够熟悉,之后再进行巩固。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值