给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
思路
栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack 仍然为空;
建立哈希表 dic 构建左右括号对应关系:key左括号,value右括号;建立栈 stack,遍历字符串 s 并按照算法流程一一判断。
如果 c 是左括号,则入栈 push;
否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 false
解决边界问题:
栈 stack 为空: 此时 stack.pop() 操作会报错;
因此,我们采用一个取巧方法,给 stack 赋初值 ? ,并在哈希表 dic 中建立 key: '?',value:'?′ 的对应关系予以配合。此时当 stack 为空且 c 为右括号时,可以正常提前返回 false;
字符串 s 以左括号结尾: 此情况下可以正常遍历完整个 s,但 stack 中遗留未出栈的左括号;
因此,最后需返回 len(stack) == 1,以判断是否是有效的括号组合。
python3解法1
class Solution:
def isValid(self, s: str) -> bool:
# 为什么要存储"?":"?",如果遇到右括号的时候,在执行dic[stack.pop()]的时候不会报错
dic = {"(":")","[":"]","{":"}","?":"?"}
# 为什么stack不能是空的,如果为空,当遇到右括号的时候,stack.pop会出错
stack = ["?"]
for c in s:
if c in dic:
stack.append(c)
elif dic[stack.pop()] != c:
return False
return len(stack) == 1
python3解法2
def isValid2(s):
if len(s) == 0 or len(s) % 2 != 0: return False
# 创建一个字典,存储括号的对应关系
char_map = {"(": ")", "{": "}", "[": "]"}
# 创建一个栈,遇到左括号就入栈,右括号就出栈
stack = []
for c in s:
if c in char_map:
# 将左括号入栈
stack.append(c)
else:
# 当前字符是右括号,则将栈顶元素出栈,找到对应右括号,判断是否与当前括号一致
if not stack or char_map[stack.pop()] != c:
return False
# 字符串遍历结束之后,栈不为空,则说明还有左括号在栈内
if len(stack) != 0:
return False
return True
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses