Question:
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.
本题难度hard。有两种算法分别是:stack和DP。
算法1:stack
【复杂度】
时间 O(N) 空间 O(N)
【思路】
用Stack的方法本质上和Valid Parentheses是一样的,一个右括号能消去Stack顶上的一个左括号。不同的是,为了能够计算括号对的长度我们还需要记录括号们的下标。这样在弹出一个左括号后,我们可以根据当前坐标减去栈中上一个(也就是Pop过后的Top元素)的坐标来得到该有效括号对的长度。
【附】
这个算法难在对各种情况的判断,以及对stack的巧妙利用。这个算法我是看了很一会才反应过来((⊙﹏⊙)b)。下面将代码贴出,对于各种情况的处理我也进行了注释。
【注意】
第26行:curLen=i-stack.peek().index;
不能是curLen=i-stack上一个pop出的index+1;
。如果对于)()()
,此时 i=4,如果按照后一种方法,算出的curLen=i-3+1
,而正确的应该是curLen=i-0
。
【代码】
算法2:DP
【复杂度】
时间 O(N) 空间 O(N)
【思路】
动态规划法将大问题化为小问题,我们不一定要一下子计算出整个字符串中最长括号对,我们可以先从后向前,一点一点计算。假设d[i]是从下标i开始到字符串结尾最长括号对长度,s[i]是字符串下标为i的括号。如果s[i-1]是左括号,如果i + d[i] + 1是右括号的话,那d[i-1] = d[i] + 1。如果不是则为0。如果s[i-1]是右括号,因为不可能有右括号开头的括号对,所以d[i-1] = 0。
【附】
我只能再次感慨DP的强大和这个算法的精妙。
【注意】
1、第16行if(end<size&&s.charAt(end)==')'){
中的end<size
必须要有,以防止(()
(当i=0,end=3越界)
2、第19行d[i]+=d[end+1];
,别错写为d[i]+=d[end];
【代码】
参考
Longest Valid Parentheses(这篇帖子无论是技术探索精神还是写作风格都值得参考)