9.栈与队列Ⅱ

9.栈与队列Ⅱ

20有效的括号

题目描述

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 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)函数实现,返回的就是数值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值