力扣Day11(2.14)| 第五章 栈和队列 (20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值 )

题一:20. 有效的括号

链接

题目链接:
视频链接:
文章链接:

视频总结

关键点

  1. 总共只有三种情况:(] ; ( ; )

编程思路

卡尔:
  1. 遇到左括号时把对应的右括号加入栈里面(遇左放右比遇左放左easy点)
  2. 遇到右括号时判断是否和栈头的一样,一样则栈pop,不一样则False
  3. 遍历到右括号,发现已经为空了,说明右多了,false
  4. 当处理完之后,如果为空就说明ture,否则false,多了左括号
  5. 考虑剪枝操作,匹配时一定是偶数个,若为奇数则是false
  6. 在循环到空栈时,先把空栈的条件放在前面,否则对空栈pop的话会异常

力扣实战

思路一:

 # 方法一,仅使用栈,更省空间
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
        
# 反思1:

思路二:

 # 方法二,使用字典
class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        mapping = {
            '(': ')',
            '[': ']',
            '{': '}'
        }
        for item in s:
            if item in mapping.keys():
                stack.append(mapping[item])
            elif not stack or stack[-1] != item: 
                return False
            else: 
                stack.pop()
        return True if not stack else False

文档总结

1. 由于栈结构的特殊性,非常适合做对称匹配类的题目。

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

链接

题目链接:
视频链接:
文章链接:

视频总结

关键点

编程思路

Me:
  1. 思路,使用栈方法,逐个加入栈,如果和栈顶相同,则pop,这样一次遍历即可
卡尔:
  1. 栈适合解决括号匹配类问题,此处字母匹配也是同样的道理
  2. 通过栈的思想来理解题目,但不一定最后使用完整的栈来实现,比如此处可以用字符串来模拟栈的效果

力扣实战

思路一:

 class Solution:
    def removeDuplicates(self, s: str) -> str:
        # 使用数组来模拟栈,当result不为空,且数组最后一个字符和当前字符相等时,才满足pop条件,否则加入栈
        result = []
        for i in s:
            if result and result[-1]==i:
                result.pop()
            else:
                result.append(i)
        return ''.join(result)
        
# 反思1:

思路二:

 # 双指针法,帅的都不谈,独立分析出流程,内啡肽直接拉满
 class Solution:
    def removeDuplicates(self, s: str) -> str:
        # 使用双指针来模拟栈;慢的功能是用来存储的,慢指向零表示栈空,此时快值直接给慢(进栈),快慢均加一
        #快加一表示下一个即将进栈的元素的索引,慢加一表示栈里已经有了一个位置了,且加一之后指向新的位置,如果有新的元素进栈,
        #则可以放在慢的加一之后的位置
        result = list(s)
        slow = fast = 0
        length = len(result)
        while fast<length:
            result[slow] = result[fast]     # 快元素即将进栈,和栈里的头元素比,如相同则正是进栈,正式进栈只需把慢加一,以为慢前面的元素表示已经在栈里面的元素。
            if slow>0 and result[slow] == result[slow-1]:   # 大于零表示栈不为空,后面就是题目判别调节
                slow -=1    #相等时慢减一,表示即将进栈的元素
            else:
                slow +=1    # 此时栈空或者不等,表示当前的快元素成功进栈,成功的标志即慢往后移动一位,表示慢前的元素在栈内,而+1后的位置表示预备进栈的元素
            fast +=1
            
        return ''.join(result[:slow])

文档总结

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

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

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

题三: 150. 逆波兰表达式求值

链接

题目链接:
视频链接:
文章链接:

视频总结

关键点

  1. 波兰表达式是一种后缀表达式,是一种利于计算机运算的形式,由二叉树的例子可见,采用后序可以在不加括号时也没有歧义
    在这里插入图片描述
    而若想让计算机顺序处理字符串就得到想要的结果,就是使用栈的方法。(来处理后缀表达式)

  2. 具体流程:遇见数字就加入到栈里面,遇见操作符时就从栈里取出两个数字进行运算,然后再把数字加入到栈里

  3. 拓展栈用法边界:相邻匹配比如左右括号匹配,比如相邻字符相同,或者相邻字符符合特殊条件就做相应的消除

编程思路

Me:

学习波兰表达式

卡尔:

在这里插入图片描述

力扣实战

思路一:

 class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        #思路:用栈的思想,用数组实现,遇到数字就进栈,遇到运算符就 取出两个元素运算然后再放进栈里
        stack = list()
        for i in tokens:
            if i =='+' or i =='-' or i =='*' or i =='/': 
                nums1 = stack[-1]   # 需要把字符串类型变为整形,否则字符串类型无法数学运算
                stack.pop()
                nums2 = stack[-1]
                stack.pop()
                if i == '+':
                    stack.append(nums1+nums2)
                elif i == '-':
                    stack.append(nums2-nums1)   # 注意减法是谁减谁
                elif i == '*':
                    stack.append(nums1*nums2)
                else:
                    stack.append(int(nums2/nums1))   # 注意除法是谁除以谁,在整数除法中,除法 / 总是返回一个浮点数,如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符 // :

            else:
                stack.append(int(i))
        return stack[-1]
        
# 反思1:本题代码需要尤其注意,字符串类型的数字不能数学运算,需要转成数字型;python除法默认获得的是浮点数,若有需要得转成整形

文档总结

1. 文档里的文字部分值得反复观看!!非常好
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值