代码随想录 day11 第五章 栈与队列part02

今日内容:

●  20. 有效的括号

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

●  150. 逆波兰表达式求值

1. 有效的括号

关联 leetcode 20. 有效的括号

  • 思路

    • 使用栈来实现有序的左右括号匹配
    • 压入对应的右括号,提升匹配对比效率
    • 有效的括号一定是左括号先出现
  • 题解

    func isValid(s string) bool {
    	//括号数量非偶数,一定不匹配
    	if len(s)%2 != 0 {
    		return false
    	}
    	//使用切片来模拟栈: 先进append(),后出stackBreaker[len(stackBreaker)-1]
    	stackBreaker := make([]rune, 0)
    	for _, v := range s {
    		switch v {
    		//匹配到左括号, 塞入对应的右括号【提升效率小技巧】
    		case '(':
    			stackBreaker = append(stackBreaker, ')')
    		case '[':
    			stackBreaker = append(stackBreaker, ']')
    		case '{':
    			stackBreaker = append(stackBreaker, '}')
    		//匹配到右括号
    		default:
    			//前面没有左括号,不符合题目要求的有序规定,直接返回不匹配
    			if len(stackBreaker) == 0 {
    				return false
    			}
    			//当前右括号之前没有对应的左括号
    			if v != stackBreaker[len(stackBreaker)-1] {
    				return false
    			}
    			//模拟 stack的pop操作
    			stackBreaker = stackBreaker[:len(stackBreaker)-1]
    		}
    	}
    	//保证栈空
    	return len(stackBreaker) == 0
    }
    

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

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

  • 思路:

    • 有栈来解决
    • 类似上一题,这题用来匹配相邻元素
  • 题外话:

    • 企业项目开发中,尽量避免递归。
      • 项目比较大的情况下,参数多,全局变量多,使用递归难以保证return条件,很容易导致无限递归(或递归层级过深),造成栈溢出错误(这种问题还不好排查!)
  • 题解

    func removeDuplicates(s string) string {
    	res := make([]rune, 0)
    	if len(s) < 2 {
    		return s
    	}
    	for _, v := range s {
    		//栈空先插入元素
    		if len(res) == 0 {
    			res = append(res, v)
    			continue
    		}
    		//元素与栈顶元素相同, 出栈
    		if v == res[len(res)-1] {
    			res = res[:len(res)-1]
    		} else {
    			res = append(res, v)
    		}
    	}
    	return string(res)
    }
    

3. 逆波兰表达式求值

关联 leetcode 150. 逆波兰表达式求值

  • 逆波兰式:

    • 后缀表达式[将运算符写在操作数之后]
      • 方便计算机做运算的表达式
        • 不用加括号优先级
        • 顺序处理
      • 二叉树的后序遍历[ 序: 中的顺序 ]
    • 依旧是 从左向右阅读
    • 永远是两个操作数然后跟一个
    • example:
      • (a+b)*c-(a+b)/e的后缀表达式为:
        • *(a+b)c-(a+b)/e
        • *→((a+b)c)((a+b)/e)-
        • *→((a+b)c)((a+b)e/)-
        • →(ab+c)(ab+e/)-*
        • *→ab+c**ab+e/-
  • 思路

    • 用栈来做相邻字符的消除操作
    • 每次遇到运算符从栈中取出两个元素
      • 进行运算
      • 将结果压栈
    • 注意操作步骤
      • 栈顶下一个元素 操作符 栈顶元素
  • 题解

    func evalRPN(tokens []string) int {
    	res := make([]int, 0)
    	for _, token := range tokens {
    		switch token {
    		case "+":
    			val1, val2 := res[len(res)-1], res[len(res)-2]
    			res = res[:len(res)-2]
    			res = append(res, val2+val1)
    		case "-":
    			val1, val2 := res[len(res)-1], res[len(res)-2]
    			res = res[:len(res)-2]
    			res = append(res, val2-val1)
    		case "*":
    			val1, val2 := res[len(res)-1], res[len(res)-2]
    			res = res[:len(res)-2]
    			res = append(res, val2*val1)
    		case "/":
    			val1, val2 := res[len(res)-1], res[len(res)-2]
    			res = res[:len(res)-2]
    			res = append(res, val2/val1)
    		default:
    			val, _ := strconv.Atoi(token)
    			res = append(res, val)
    		}
    	}
    	return res[0]
    }
    

总结

  • 栈适合用来做相邻字符的消除操作
    • 相邻括号的匹配
    • 后缀运算符

  • 35
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值