个人评价:栈使用的典型场景,最近正好梳理到栈,其实还是蛮有趣的~
题目难度:🌟 (参考 LeeCode 简单🌟 、中等🌟 🌟 、困难🌟 🌟 🌟 )
另,通常算法题会考察分析时间复杂度和空间复杂度,可参考笔者之前的文章
「数据结构&算法」必知必会系列:3. 时间 & 空间复杂度(下)
对栈不熟悉的,建议先参考阅读:「数据结构&算法」必知必会系列:8. 常见数据结构——栈
有效的括号
题目描述
给定一个只包括 ‘(',')','{','}','[',']’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
示例 4:
输入:s = “([)]”
输出:false
示例 5:
输入:s = “{[]}”
输出:true
提示:
1 <= s.length <= 104 s 仅由括号 ‘()[]{}’ 组成
解题思路
栈的典型使用场景(此题其他方法笔者暂未研究)栈解题的思路如下:
- 字符串的长度为奇数,我们可以直接返回 false,省去后续的遍历判断过程。
- 栈保存未匹配的左括号。从左到右遍历字符串,为左括号,将其压入栈。
- 当遍历至到右括号,如果能够匹配,比如“(”跟“)”匹配,“[”跟“]”匹配,“{”跟“}”匹配,则继续扫描剩下的字符串,并从栈顶取出一个匹配的左括号;否则,则返回 false。
- 当所有的括号都扫描完成之后,如果栈为空,则说明字符串为合法格式,返回 true;否则,则返回 false。
Go 代码如下:
func isValid(s string) bool {
sLen := len(s)
if sLen%2 != 0 {
return false
}
pairMap := map[byte]byte{
')': '(',
']': '[',
'}': '{',
}
stack := []byte{} // 初始化栈
for i := 0; i < sLen; i++ { //遍历字符串
if pairMap[s[i]] > 0 { //是否右括号
if len(stack) == 0 || stack[len(stack)-1] != pairMap[s[i]] { //栈为空 或者 出栈不匹配
return false
}
stack = stack[:len(stack)-1] //出栈
} else { //左括号 =》入栈
stack = append(stack, s[i])
}
}
return len(stack) == 0
}
https://goplay.tools/snippet/cLjqRr1VTvL Go play~
复杂度?🙌 时间 O(n) 空间 O(n)
总结
栈的经典应用,此类需要用到 LIFO 后进先出思想的都可利用栈哦~
顺序栈(数组实现栈)的入栈push 和出栈pop方法也熟记一下(不就是append元素以及截取最后一个元素嘛)
stack = append(stack, input) //push
stack = stack[:len(stack)-1] //pop