代码随想录算法训练营第11天|栈与队列| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

代码随想录算法训练营第11天|栈与队列| 20. 有效的括号 、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

20. 有效的括号

题目链接: 20. 有效的括号

自己做

思想:

是左括号,就进栈,遇到右括号,就出栈,一旦发现不匹配,就失败

自己做时,一些特殊的情况没有考虑到,导致不能一边运行成功。

代码:

python

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        # 思想:
        '''
        是左括号,就进栈,遇到有括号,就出栈,一旦发现不匹配,就失败
        '''
        if len(s) == 0:
            return False

        stack = []

        for i in range(len(s)):
            if s[i] == '(' or s[i] == '{' or s[i] == '[':
                stack.append(s[i])
            elif s[i] == ')' and len(stack) != 0:
                val = stack.pop()
                if val == '(':
                    continue
                else:
                    return False
            elif s[i] == '}' and len(stack) != 0:
                val = stack.pop()
                if val == '{':
                    continue
                else:
                    return False
            elif s[i] == ']' and len(stack) != 0:
                val = stack.pop()
                if val == '[':
                    continue
                else:
                    return False
            else:
                return False
        if not stack:
            return True
        else:
            return False

代码随想录

思想:

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。

有三种不匹配的情况:

  1. 左方向的括号多余了

    已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

  2. 括号没有多余,但是 括号的类型没有匹配上

    遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

  3. 右方向的括号多余了

    遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

代码:

python

# 方法一,仅使用栈,更省空间

## 这里有一个小技巧:还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!
class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        
        for item in s:
            if item == '(':
                stack.append(')')
            elif item == '[':
                stack.append(']')
            elif item == '{':
                stack.append('}')
            elif not stack or stack[-1] != item:
                return False
            else:
                stack.pop()
        
        return True if not stack else False

c++

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        //先剪枝
        if(s.size() % 2 != 0){
            return false;
        }
        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('}');
            }else if(!st.empty() && s[i] == st.top()){
                st.pop();
            }else{ //第二种第三种情况
                return false;
            }
        }
        if(!st.empty()){//第一种情况
            return false;
        }
        return true;
        /* 也可以这样写
		return st.empty();
		*/

    }
};

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

题目链接: 1047. 删除字符串中的所有相邻重复项

自己做

思想:

这道题比较简单,只需要循环到当前元素时,将栈顶的元素取出来进行比较再进行下一步操作就好了。

代码:

python

class Solution(object):
    def removeDuplicates(self, s):
        """
        :type s: str
        :rtype: str
        """
        stack = []

        for char in s:
            # 如果stack==[]直接进栈
            if not stack:
                stack.append(char)
            else:
                val = stack.pop()
                if val == char:
                    continue
                else:
                    stack.append(val)
                    stack.append(char)
        
        return ''.join(stack)
                


代码随想录

思想:

和自己想的一样,想法比较好想到

代码:

# 方法一,使用栈
class Solution:
    def removeDuplicates(self, s: str) -> str:
        res = list()
        for item in s:
            if res and res[-1] == item:
                res.pop()
            else:
                res.append(item)
        return "".join(res)  # 字符串拼接

注意:

递归的实现就是

每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

c++

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

150. 逆波兰表达式求值

题目链接: 150. 逆波兰表达式求值

** 自己做**

思想:

逆波兰表达式其实就是标准算数表达式即中序遍历的后序遍历形式,这个用栈来解决!

但是题中强调两个整数之间的除法总是 向零截断 ,这地方需要特殊处理

代码:

python

import math
class Solution(object):
    def compute(self, num1, num2, char):
        if char == '+':
            return num1 + num2
        elif char == '-':
            return num1 - num2
        elif char == '*':
            return num1 * num2
        elif char == '/':
            #print(int((float(num1)/float(num2))))
            return int((float(num1)/float(num2)))

    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        stack = []

        for char in tokens:
            if char in ['+', '-', '*', '/']:
                # 出栈两个,进行运算,结果压入栈中
                num2 = stack.pop()
                num1 = stack.pop()
                result = self.compute(num1, num2, char)
                stack.append(result)
            else:
                stack.append(int(char))

        return stack.pop()

代码随想录

思想:

给你一个后缀遍历的表达式字符串数组,让你计算这个表达式的值,要想到用栈来解决
语言熟知就进栈,遇到符号就出栈,计算结果,再把结果压入栈,最后栈里面的数值就是整个表达式的结果

代码:

本题代码随想录给的代码**两个整数之间的除法总是 向零截断 **部分的处理错误

python

from operator import add, sub, mul

class Solution:
    op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
    
    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for token in tokens:
            if token not in {'+', '-', '*', '/'}:
                stack.append(int(token))
            else:
                op2 = stack.pop()
                op1 = stack.pop()
                stack.append(self.op_map[token](op1, op2))  # 第一个出来的在运算符后面
        return stack.pop()

c++

注意:
做题时有以下几点困惑:
c++中string 类型,是类的实例吗,还是基本数据类型…
答:是类,初始化就是实例
string类型" "如何转换成char’ '类型
答:后面慢慢解答吧
char ’ ’ 类型的数字如何转换成 int 类型的数值
答:固定函数stoi, stol, stoll, 也可以自己实现力扣18
想用switch函数来判断符号来着,但是说switch©c不能为字符串类型,那什么类型符合呢?

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(int i = 0; i < tokens.size(); i++){
            if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
                int nums1 = st.top();
                st.pop();
                int nums2 = st.top();
                st.pop();
                if(tokens[i] == "+") st.push(nums2 + nums1);
                if(tokens[i] == "-") st.push(nums2 - nums1);
                if(tokens[i] == "*") st.push(nums2 * nums1);
                if(tokens[i] == "/") st.push(nums2 / nums1);
            }else{
                st.push(stoi(tokens[i]));
            } 
        }
        return st.top();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值