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

20. Valid-parentheses

思路

用stack

遇到左边的就存进去,右边的pop出来,看等不等于,最后len == 0

在stack内直接存入对应的右边的符号

    def isValid(self, s: str) -> bool:
        if s is None or len(s) == 0:
            return True
        if len(s) == 1:
            return False
        stack = []

        for sign in s:
            if sign == "(":
                stack.append(")")
            elif sign == "{":
                stack.append("}")
            elif sign =="[":
                stack.append("]")
            else:
                if len(stack) == 0 or stack.pop() != sign:
                    return False
        return len(stack) == 0

栈的应用:

cd a/b/c/../../

题目分析

不匹配的情况:

第一种情况,字符串里左方向的括号多余了 ,所以不匹配。

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

第二种情况,括号没有多余,但是 括号的类型没有匹配上。

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

第三种情况,字符串里右方向的括号多余了,所以不匹配。

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

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

1047. Remove-all-adjacent-duplicates-in-string

思路

我拿到题的时候完全没想到要用stack,还在想着遍历整个string比较,stack明显更加简单,知道要用stack以后就好写很多

栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素,然后再去做对应的消除操作

    def removeDuplicates(self, s: str) -> str:
        stack = []

        for char in s:
            if len(stack) == 0:
                stack.append(char)
            else:
                prev = stack.pop()
                if prev != char:
                    stack.append(prev)
                    stack.append(char)
        return "".join(stack)

栈分析

如何想到栈:

栈可以调用上一个参数,所以如果要和前面的进行比较的话,可以想想能不能用stack

题外话

游戏开发可能使用栈结构,编程语言的一些功能实现也会使用栈结构,实现函数递归调用就需要栈,但不是每种编程语言都支持递归,例如:递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因

相信大家应该遇到过一种错误就是栈溢出,系统输出的异常是Segmentation fault(当然不是所有的Segmentation fault 都是栈溢出导致的) ,如果你使用了递归,就要想一想是不是无限递归了,那么系统调用栈就会溢出。

而且在企业项目开发中,尽量不要使用递归!在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)

150. Evaluate polish notation

思路

遇到数字就加入stack,遇到符号就pop出来俩个计算。注意的是,一直debug有问题,除法那里要int(a/b),不能直接(a//b)

    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for s in tokens:
            if s == "+":
                stack.append(stack.pop() + stack.pop())
            elif s == "*":
                stack.append(stack.pop() * stack.pop())
            elif s == "/":
                b = stack.pop()
                a = stack.pop()
                stack.append(int(a / b))
            elif s == "-":
                b = stack.pop()
                a = stack.pop()
                stack.append(a - b)
            else:
                stack.append(int(s))
        print("stack", stack)
        return stack.pop()
  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

总结

一些比较经典的题用stack就不用多说,有些题如果看到要比较上一个参数的话可以想想是否能用stack做

你可能感兴趣的:(算法,java,数据结构)