Description:
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.
Solution:
TLE solution:
we can use dp[i][j] to represent the valid parentheses number.
if( str[i], str[j] is a pair):
dp[i][j] = dp[i+1][j-1] + 1
else:
dp[i][j] = dp[i+1][j-1]
<span style="font-size:18px;">import java.util.*;
public class Solution{
public int longestValidParentheses(String s) {
if (s == null)
return 0;
int n = s.length();
if (n == 0)
return 0;
char ch1, ch2;
int dp[][] = new int[n][n];
for (int i = 0; i + 1 < n; i++) {
ch1 = s.charAt(i);
ch2 = s.charAt(i + 1);
if (ch1 == '(' && ch2 == ')')
dp[i][i + 1] = 1;
}
int j;
int max = 0;
for (int len = 3; len <= n; len++) {
for (int i = 0; (j = i + len - 1) < n; i++) {
ch1 = s.charAt(i);
ch2 = s.charAt(j);
if (ch1 == '(' && ch2 == ')') {
dp[i][j] = dp[i + 1][j - 1] + 1;
} else
dp[i][j] = dp[i + 1][j - 1];
max = Math.max(dp[i][j], max);
}
}
return max;
}
}</span>
Since we get a TLE on this, we may change to another solution, use a stack.
<span style="font-size:18px;">import java.util.*;
public class Solution {
public int longestValidParentheses(String s) {
if (s == null)
return 0;
int n = s.length();
if (n == 0)
return 0;
int max = 0;
Stack<Integer> stack = new Stack<Integer>();
int start = 0;
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '(')
stack.push(i);
else {
if (!stack.isEmpty()) {
stack.pop();
if (stack.isEmpty())
max = Math.max(max, i - start + 1);
else
max = Math.max(max, i - stack.peek() + 1);
} else {
start = i + 1;
}
}
}
return max;
}
public static void main(String[] args) {
Solution s = new Solution();
String str = "(()";
System.out.println(s.longestValidParentheses(str));
}
}</span>
Attention to the following two codes, they seem to have same functions, but are completely different. What we need here is the second one. Just feel the difference.
<span style="font-size:18px;">first = stack.pop();
if (stack.isEmpty())
max = Math.max(max, i - start + 1);
else
max = Math.max(max, i - first + 1);</span>
Second segment of codes
<span style="font-size:18px;">stack.pop();
if (stack.isEmpty())
max = Math.max(max, i - start + 1);
else
max = Math.max(max, i - stack.peek());</span>