Problem:
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.
Idea:
这道题思路不难得出,但是很容易超时,这也是leetcode里难度为hard的原因。
一开始想到的办法是,直接暴力地两两截取某段substring,判断是否为valid parentheses,一个O(n2)的方法。
更优解是用栈的思想。成功配对的话就pop,不成功就push。但是仍然超时。原因是,我执着于正向计算valid parentheses的区间,而把若干个小的子区间并成大的完整区间比较耗时。
一个比较好的解决办法是,反向计算成功配对的区间。使用栈的方法计算一遍之后(O(n)), 再遍历一遍仍然在栈里面的未匹配成功的元素,从而得知未匹配元素的区间,进而取反求得成功匹配元素的区间。时间复杂度近似为O(n).
Reference:
- Scan the string from beginning to end.
- If current character is ‘(’,
push its index to the stack. If current character is ‘)’ and the
character at the index of the top of stack is ‘(’, we just find a
matching pair so pop from the stack. Otherwise, we push the index of
’)’ to the stack.- After the scan is done, the stack will only
contain the indices of characters which cannot be matched. Then
let’s use the opposite side - substring between adjacent indices
should be valid parentheses.- If the stack is empty, the whole input
string is valid. Otherwise, we can scan the stack to get longest
valid substring as described in step 3.
Solution:
一个很酷的python解法
def longestValidParentheses(self, s):
stack, res, s = [0], 0, ')'+s
for i in xrange(1, len(s)):
if s[i] == ')' and s[stack[-1]] == '(':
stack.pop()
res = max(res, i - stack[-1])
else:
stack.append(i)
return res
我的辣鸡解法
class Solution(object):
def longestValidParentheses1(self, s):
"""
:type s: str
:rtype: int
"""
max_num=0
i=0
j=1
length=len(s)
l=list()
if length==0:
return 0
else:
l.append([s[0],0])
i=0
while j <length:
if len(l)==0:
l.append([s[j],j])
j+=1
i+=1
elif l[i][0]=='(' and s[j]==')':
l.pop()
i-=1
j+=1
else:
l.append([s[j],j])
j+=1
i+=1
if len(l)==0:
return length
elif len(l)==1:
return l[0][1] if l[0][1] > length-l[0][1]-1 else length-l[0][1]-1
else:
max_num = l[0][1]
for i in xrange(0,len(l)-1):
a=l[i][1]
b=l[i+1][1]
if b-1 != a:
max_num = max_num if max_num > b-a-1 else b-a-1
if i==len(l)-2:
max_num = max_num if max_num > length-b-1 else length-b-1
return max_num