Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
For "(()"
, the longest valid parentheses substring is "()"
, which has length = 2.
Another example is ")()())"
, where the longest valid parentheses substring is "()()"
, which has length = 4.
Subscribe to see which companies asked this question
class Solution(object):
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
stack = []
max_len = 0
for i in range(len(s)):
if s[i] == '(':
stack.append((s[i], i))
else:
if len(stack) != 0 and stack[-1][0] == '(':
stack.pop()
if len(stack) == 0:
cur_len = i + 1
else:
cur_len = i - stack[-1][1]
max_len = max(max_len, cur_len)
else:
stack.append((s[i], i))
return max_len
我之前考虑的是不使用栈,仅使用一个数字表示栈中有多少个左括号。但是发现这样子是不行的。原因有这两个:
1、新的右括号进入后,需要上一个没有被消去的左括号的下标,计算这一次括号匹配的长度
2、如果新的右括号没有被左括号消去,那么右括号也需要入栈,作为一个标志,以后的右括号就不能消去这个右括号了。
所以入栈的元素应该是('(', index)这样的一个元组。以上方法可以叫做栈方法。
在大神的文章:点击打开链接
里面,还看到了动态规划算法,和不需要额外空间的解法:
class Solution(object):
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
dp = [0]*len(s)
for i in range(1, len(s)):
if s[i] == ')':
left = i - dp[i - 1] - 1
if left >= 0 and s[left] == '(':
dp[i] = 2 + dp[i-1]
if left > 0:
dp[i] += dp[left - 1]
dp.append(0)
return max(dp)
把从后向前的改成从前向后的了
Q:能否不用额外空间求解?A:可以,但是要提高时间复杂度。比如((()()),先遍历一遍将所有的()替换成00,得到((0000),再遍历一遍,替换所有的(00...00)这种形式字符串为000...000,这里我们得到(000000,直到遍历完无法替换更多括号为之。如果所有符号都是0,说明是有效的。这样的时间复杂度是O(N)。