今日内容:
● 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/-
- (a+b)*c-(a+b)/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] }
总结
- 栈适合用来做相邻字符的消除操作
- 相邻括号的匹配
- 后缀运算符