'('
and
')'
, find the length of the longest valid (well-formed) parentheses substring.
"(()"
, the longest valid parentheses substring is
"()"
, which has length = 2.
")()())"
, where the longest valid parentheses substring is
"()()"
, which has length = 4.
We can fill the dp array from the right to left. dp[s.length()-1] is definitely 0. Consider the case of “((….))“, for position i, the next position after the substring represented by dp[i+1] is j = i + dp[i+1] + 1. If dp[j] is a matched “)”, then dp[i] is dp[i+1] + 2. There could also be the case that since the “)” at dp[j] is matched, the substring after dp[j] is also connected, Consider ((….))(….), in this case, we add dp[j+1] to dp[i].
The total time complexity for dynamic programming is O(n), and space complexity is O(1).
Update 1/16/2015:
Method 2 is the solution I’m most comfortable with.
1: public class Solution {
2: public int longestValidParentheses(String s) {
3: if(s == null || s.length() == 0){
4: return 0;
5: }
6: int maxLen = 0;
7: int last = -1;
8: Stack<Integer> stack = new Stack<Integer>();
9: for(int i = 0; i < s.length(); i++){
10: char c = s.charAt(i);
11: if(c == '('){
12: stack.add(i);
13: }
14: else {
15: //the ( is unmatched, it means the end of the previous group
16: if(stack.isEmpty()){
17: last = i;
18: }
19: else{
20: stack.pop();
21: if(stack.isEmpty()){
22: maxLen = Math.max(maxLen, i - last);
23: } else{
24: maxLen = Math.max(maxLen, i - stack.peek());
25: }
26: }
27: }
28: }
29: return maxLen;
30: }
31: }
1: public class Solution {
2: public int longestValidParentheses(String s) {
3: if(s == null || s.length() == 0){
4: return 0;
5: }
6: int maxLen = 0;
7: //start a dp array, dp[i] is the length of the valid longestvalidparenthese starting at i
8: int[] dp = new int[s.length()];
9: //any string starting at the end is not valid
10: dp[dp.length-1] = 0;
11: for(int i = dp.length -2; i >= 0; i--){
12: if(s.charAt(i) == ')'){
13: dp[i] = 0;
14: continue;
15: }
16: //the first character after the substring represented by dp[i+1]
17: int j = i + dp[i+1] + 1;
18: if(j < s.length() && s.charAt(j) == ')'){
19: // for the situation like ((....))
20: dp[i] = dp[i+1] + 2;
21: // for the situation like ((....))()
22: if(j + 1 < s.length()){
23: dp[i] += dp[j+1];
24: }
25: }
26: maxLen = Math.max(dp[i], maxLen);
27: }
28: return maxLen;
29: }
30: }