20.有效括号
https://leetcode-cn.com/problems/valid-parentheses/
题目描述
方法 1:栈
思路
遇到左括号就入栈。
遇到右括号就从栈中弹出一个元素,判断两者是否是匹配的一对括号。
代码
JavaScript Code
复杂度分析
时间复杂度:$O(n)$,n 为字符串的长度。
空间复杂度:$O(n)$,n 为字符串的长度。
方法 2:递归
思路
产品经理法(⓿_⓿) 假设我们现在已经有了一个 isValid
方法,可以验证一个字符串 s 是否由有效括号组成。
那么子问题是什么?
如果 s 的第一个字符是左括号的话,那我们应该可以找到它对应右括号的下标 index,如果找不到说明就不是有效括号啦。
如果找到了,那么现在问题就变成了:
(0, index) 中间这段字符串是否包含有效括号?
(index, s.length) 这段字符串是否包含有效括号?
开括号表示不包括边界
大问题和小问题的关系是什么?
显然必须两个小问题的结果都是 true 才行啦,也就是:
isValid(s) = isValid(1, index - 1) && isValid(index + 1, s.length)
递归出口在哪里?
如果字符串第一个字符不是左括号,
return false
如果字符串为空,
return true
还有一个,如果字符串长度是奇数的话,我们也可以提前
return false
。
关于如何找到对应的右括号下标
用一个 counter
来记录当前遇到的括号,比如,我们要找的是 '(' 的对应右括号 ')',那么在遍历字符串时:
遇到 '(' 时
counter++
遇到 ')' 时
counter--
当
counter === 0
时说明我们找到了如果遍历结束后
counter > 0
说明找不到匹配的右括号
代码
JavaScript Code
复杂度分析
时间复杂度:TODO
空间复杂度:$O(n)$,n 为字符串的长度,调用栈的最大深度是 $n/2$。
方法 3:正则
思路
不断地把 ()
{}
[]
替换成空字符,直到:
s 变成了空字符,那么结果就是
true
,或者,s 长度不为空,但是 s 中已经没有
()
,{}
或者[]
括号对了,那么结果就是false
。
代码
JavaScript Code
复杂度分析
时间复杂度:$O(n)$,n 为字符串的长度。最坏的情况下,每次循环只能替换一对括号,比如 "(((((())))))",需要循环 n/2 次。
空间复杂度:$O(1)$。
Last updated
Was this helpful?