Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()" Output: 2 Explanation: The longest valid parentheses substring is "()"
Example 2:
Input: ")()())" Output: 4 Explanation: The longest valid parentheses substring is "()()"
1. Brute Force
public class Solution {
private static Dictionary<string, bool> dict = new Dictionary<string, bool>();
public int LongestValidParentheses(string s) {
int maxlen = 0;
for (int i = 0; i < s.Length; ++i) {
if (s.Length - i < maxlen) break;
int j = (s.Length - i) % 2 == 0 ? s.Length : s.Length - 1;
for (; j >= i + 2; j -= 2) {
if (j - i < maxlen) break;
string key = s.Substring(i, j - i);
if (!dict.Keys.Contains(key)) dict[key] = IsValid(key);
if (dict[key]) {
maxlen= Math.Max(maxlen, j - i);
break;
}
}
}
return maxlen;
}
public bool IsValid(string s) {
Stack<char> a = new Stack<char>();
for (int i = 0; i < s.Length; ++i) {
if (s[i] == '(') a.Push('(');
else if (a.Count > 0 && a.Peek() == '(') a.Pop();
else return false;
}
return a.Count == 0;
}
}
2. Using Dynamic Programming
public class Solution {
public int LongestValidParentheses(string s) {
int maxlen = 0;
int[] dp = new int[s.Length];
for (int i = 1; i < s.Length; ++i) {
if (s[i] == ')') {
if (s[i - 1] == '(') {
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
}
else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') {
dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
}
maxlen = Math.Max(maxlen, dp[i]);
}
}
return maxlen;
}
}
3. Using Stack
public class Solution {
public int LongestValidParentheses(string s) {
int maxlen = 0;
Stack<int> a = new Stack<int>();
a.Push(-1);
for (int i = 0; i < s.Length; ++i) {
if (s[i] == '(') a.Push(i);
else {
a.Pop();
if (a.Count == 0) a.Push(i);
else maxlen = Math.Max(maxlen, i - a.Peek());
}
}
return maxlen;
}
}
4. Without extra space
public class Solution {
public int LongestValidParentheses(string s) {
int maxlen = 0, left = 0, right = 0;
for (int i = 0; i < s.Length; ++i) {
if (s[i] == '(')
++left;
else
++right;
if (left == right)
maxlen = Math.Max(maxlen, 2 * right);
else if (right >= left)
left = right = 0;
}
left = right = 0;
for (int i = s.Length - 1; i >= 0; --i) {
if (s[i] == '(')
++left;
else
++right;
if (left == right)
maxlen = Math.Max(maxlen, 2 * left);
else if (left >= right)
left = right = 0;
}
return maxlen;
}
}