DAY11 有效的括号 删除字符串中的所有相邻重复项 逆波兰表达式求值

20. 有效的括号

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

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

  • 输入: "()"
  • 输出: true

示例 2:

  • 输入: "()[]{}"
  • 输出: true

示例 3:

  • 输入: "(]"
  • 输出: false

示例 4:

  • 输入: "([)]"
  • 输出: false

示例 5:

  • 输入: "{[]}"
  • 输出: true

这题拿栈做就很简单了,思路如下图:

这是我的解法,与上图类似

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

这是完完全全图上的解法

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

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

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

  • 输入:"abbaca"
  • 输出:"ca"
  • 解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

  • 1 <= S.length <= 20000
  • S 仅由小写英文字母组成。

做法跟前一个题一模一样,但是可以用字符串直接模拟栈

栈解法:

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

栈解法还要全部弹出来再翻转,还挺麻烦的,下面的字符串解法:

class Solution {
public:
    string removeDuplicates(string s) {
          string a;
          for(int i=0;i<s.size();i++)
          {
              if(a.empty()||a.back()!=s[i])
              {
                  a.push_back(s[i]);
              }
              else
              a.pop_back();
          }
         
          return a;
    }
};

150. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + ,  - ,  * ,  / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

  • 输入: ["2", "1", "+", "3", " * "]
  • 输出: 9
  • 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

  • 输入: ["4", "13", "5", "/", "+"]
  • 输出: 6
  • 解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。

  • 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。

一开始不知道这是啥,看到最后一句话,恍然大悟。

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long int> st;
        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
            {
                long long int a=st.top();
                st.pop();
                long long int b=st.top();
                st.pop();
                if(tokens[i]=="+")st.push(a+b);
                else if(tokens[i]=="-")st.push(b-a);
                else if(tokens[i]=="*")st.push(a*b);
                else if(tokens[i]=="/")st.push(b/a);
            }
            else
            st.push(stoll(tokens[i]));
        }
        return st.top();
    }
};

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我来回答你的问题。 1. 给出一个字符串,找出字符串所有的单词。 可以通过正则表达式来实现,代码如下: ```javascript const str = "hello world, I'm a developer"; const words = str.match(/\b\w+\b/g); console.log(words); // ["hello", "world", "I'm", "a", "developer"] ``` 这里使用了 `\b\w+\b` 匹配单词的正则表达式,其 `\b` 表示单词边界,`\w+` 表示匹配一个或多个字母数字下划线字符。 2. 从键盘输入两个字符串,在第一个字符串删除第二个字符串的字符。 可以先将第二个字符串转换为字符数组,然后遍历该数组,在第一个字符串删除对应的字符。代码如下: ```javascript const str1 = "hello world"; const str2 = "o"; const chars = str2.split(""); for (let i = 0; i < chars.length; i++) { const char = chars[i]; str1 = str1.replace(new RegExp(char, "g"), ""); } console.log(str1); // "hell wrld" ``` 这里使用了 `split` 将第二个字符串转换为字符数组,然后遍历该数组,使用 `replace` 在第一个字符串删除对应的字符。 3. 使用正则表达式匹配日期格式,如 2022年11月30日。 可以使用如下正则表达式匹配日期格式: ```javascript const str = "2022年11月30日"; const dateRegex = /(\d{4})年(\d{1,2})月(\d{1,2})日/; const match = str.match(dateRegex); const year = match[1]; const month = match[2]; const day = match[3]; console.log(`${year}-${month}-${day}`); // "2022-11-30" ``` 这里使用了 `(\d{4})年(\d{1,2})月(\d{1,2})日` 匹配日期格式的正则表达式,其 `(\d{4})` 表示匹配 4 个数字的年份,`(\d{1,2})` 表示匹配 1 到 2 个数字的月份和日期。然后使用 `match` 方法匹配字符串,获取到匹配的年份、月份和日期,并使用模板字符串拼接成标准日期格式输出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值