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
Understand the problem:")()())"
, where the longest valid parentheses substring is "()()"
, which has length = 4.The problem asks for finding the length of the longest valid parentheses substring. Note that it is substring not subsequence.
Solution 1: Using DP
For those kinds of "longest substring" problems, it is usually to use DP solution. This problem is kind of special using the DP solution.
1. Define dp[n], whereas dp[i] means the length of the longest valid parentheses substrings STARTING FROM i to str.length() - 1.
2. Transit function.
-- If the str[i] = ')', dp[i] = 0, because there will no well-formed parentheses starting from ')'.
-- If the str[i] = '(', we check dp[i + 1], the longest valid parentheses starting from i + 1, and jump to the index j = i + dp[i + 1] + 1. e.g.
( ( ) ( ) )
i j
So if j is within the length of the string and str[j] == ')', dp[i] = dp[i + 1] + 2. In addition, dp[i] += dp[j + 1], because what if after j the parentheses are still valid.
3. Initial state: dp[n - 1] = 0
4. Final state: It is quite special here. We cannot check dp[0] because dp[i] stands for the length of longest valid parentheses starting from i. So the longest substring may not starts from str[0]. As a result, we must check if dp[i] is the largest. So the final state is max(dp[i]).
Code (Java):
public class Solution { public int longestValidParentheses(String s) { if (s == null || s.length() < 2) { return 0; } int[] dp = new int[s.length()]; int maxLen = 0; for (int i = s.length() - 2; i >= 0; i--) { if (s.charAt(i) == '(') { int j = i + dp[i + 1] + 1; if (j < s.length() && s.charAt(j) == ')') { dp[i] = dp[i + 1] + 2; if (j + 1 < s.length()) { dp[i] += dp[j + 1]; } } } maxLen = Math.max(maxLen, dp[i]); } return maxLen; } }
Solution 2: Using a stack
public class Solution { public int longestValidParentheses(String s) { if (s == null || s.length() < 2) { return 0; } Stack<Integer> stack = new Stack<Integer>(); int max = 0; int start = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '(') { stack.push(i); } else { if (stack.isEmpty()) { start = i + 1; } else { stack.pop(); if (stack.isEmpty()) { max = Math.max(max, i - start + 1); } else { max = Math.max(max, i - stack.peek()); } } } } return max; } }
No comments:
Post a Comment