【栈与队列】力扣20:有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例1:
输入:s = "()[]{}"
输出:true
示例2:
输入:s = "([)]"
输出:false
- 栈
括号匹配是典型的使用后进先出的栈来解决的问题,既可以满足匹配,又可以满足括号闭合的正确顺序。
从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。
为了快速判断括号的类型,可以使用哈希表存储每一种括号实现快速配对(而不是写一堆elif)。哈希表(字典)的【键】为右括号,【值】为相同类型的左括号。
在遍历结束后,如果栈中没有左括号,说明字符串 s 中的所有左括号闭合,返回 True,否则返回 False。
提前返回False:注意到有效字符串的长度一定为偶数,因此如果字符串的长度为奇数,可以直接返回 False,省去后续的遍历判断过程。
class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2 == 1:
return False
pairs = {')': '(', '}': '{', ']': '['} # 哈希表的key是右括号,value是左括号
stack = [] # 定义栈
for char in s:
if char in pairs:
if not stack or stack[-1] != pairs[char]: # 栈为空or栈顶元素不属于六种符号的情况
return False
stack.pop() # else的情况
else:
stack.append(char)
return not stack # 如果括号全部匹配完成并被弹出,最后的栈就是空栈,返回True;只要栈中还有元素,说明没有完全匹配,那么返回False
另一种代码,两个if位置不一样
class Solution:
def isValid(self, s: str) -> bool:
pairs = {')': '(', '}': '{', ']': '['} # 哈希表的key是右括号,value是左括号
stack = [] # 定义栈
for char in s:
if stack and char in pairs: # 栈不为空 且 字符串的元素属于6种规定符号,才进行匹配
if stack[-1] == pairs[char]: # 栈顶是左括号 且 与整个char的value相等,就可以弹出
stack.pop()
else: # 栈顶没有匹配的元素则直接返回False
return False
else: # 栈为空 or 元素不属于6种规定符号,入栈
stack.append(char)
return not stack
小技巧解决边界问题:
- 栈 stack 为空:此时 stack.pop() 操作会报错;因此,采用一个取巧方法,给 stack 赋初值
?,并在哈希表 pairs 中建立 key:?,value:?的对应关系予以配合。此时当 stack 为空且 char 为右括号时,可以正常提前返回 false; - 字符串 s 以左括号结尾:此情况下可以正常遍历完整个 s,但 stack 中遗留未出栈的左括号;因此,最后需返回 len(stack) == 1,以判断是否是有效的括号组合。
class Solution:
def isValid(self, s: str) -> bool:
dic = {'{': '}', '[': ']', '(': ')', '?': '?'}
stack = ['?'] # 初始化栈
for c in s:
if c in dic: stack.append(c)
elif dic[stack.pop()] != c: return False
return len(stack) == 1 # 栈有初始值?,所以如果匹配全部成功,最后应当剩一个值
作者:jyd
链接:https://leetcode.cn/problems/valid-parentheses/solution/valid-parentheses-fu-zhu-zhan-fa-by-jin407891080/
时间复杂度:O(n),其中 n 是字符串 s 的长度。遍历了一遍字符串。
空间复杂度:O(n + ∣Σ∣),其中 Σ 表示字符集,本题中字符串只包含 6 种括号,∣Σ∣ = 6。栈中的字符数量为 O(n),而哈希表使用的空间为 O(∣Σ∣),相加即可得到总空间复杂度。最坏情况下,假如输入是 (((((((,栈的大小将是输入字符串的长度。
- 消消乐 - 字符串替换
@ Java
class Solution {
public boolean isValid(String s) {
while(true){
int l=s.length();
s=s.replace("()","");
s=s.replace("{}","");
s=s.replace("[]","");
if(s.length()==l){return l==0;}
}
}
}
写出的python版本超出时间限制
class Solution:
def isValid(self, s: str) -> bool:
while True:
l = len(s)
s = s.replace('()', '')
s = s.replace('[]', '')
s = s.replace('{}', '')
if len(s) == 1:
return l == 0
- ASCⅡ码
@ C++
class Solution {
public:
bool isValid(string s) {
if(s == ""){
return true;
}
vector<char> stack;
stack.push_back(s[0]);
for(int i=1; i<s.size(); i++){
if(stack.empty() == true){
stack.push_back(s[i]);
}else if(s[i] - stack.back() == 1 || s[i] - stack.back() == 2){
stack.pop_back();
} else {
stack.push_back(s[i]);
}
}
return stack.empty();
}
};

浙公网安备 33010602011771号