这一题有三种解法
第一种解法利用栈将不合法的括号的下标留在栈里----还记得怎么利用栈判断一组括号是否合法吗;)
也是我第一次做的时候想到的方法,这次重新改了下代码,让它看起来更加优雅
int longestValidParentheses(string s) {
int length = s.length();
if (length < 2)
return 0;
vector<int> indexStack;
int maxLength = 0;
for (int index = 0; index < length; index++)
{
if (s[index] == ')' && !indexStack.empty() && s[indexStack.back()] == '(')
{
indexStack.pop_back();
if (!indexStack.empty()) maxLength = max(maxLength, index - indexStack.back());
else maxLength = max(maxLength, index + 1);
continue;
}
indexStack.push_back(index);
}
return maxLength;
}
第二种解法是一维DP,https://oj.leetcode.com/discuss/8092/my-dp-o-n-solution-without-using-stack 有详细的介绍。dp[i]是以i为尾巴的最长的括号对的长度
有以下两种情况
s[i] == '(':dp[i] = 0, 因为以'('结尾的字符串不是合法的括号对
s[i] == ')' :
s[i-1] == '(':dp[i] = dp[i-2] + 2 ==>()()
s[i-1] == ')' && s[i-dp[i-1]-1] == '(':dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2] ==>()(())
int longestValidParentheses(string s) {
int n = s.size();
if (n <= 1) return 0;
int* dp = new int[n];
memset(dp, 0, sizeof (int) * n);
int maxl = 0;
for (int i = 1; i < n; i++)
{
if (s[i] == ')')
{
if (s[i-1] == '(')
dp[i] = i - 2 > 0 ? 2 + dp[i - 2] : 2;
else if (s[i-1] == ')' && i - dp[i - 1] - 1 >= 0 && s[i - dp[i - 1] - 1] == '(')
dp[i] = 2 + dp[i - 1] + (i - dp[i - 1] - 2 > 0 ? dp[i - dp[i - 1] - 2] : 0);
maxl = max(maxl, dp[i]);
}
}
delete[] dp;
return maxl;
}
第三种方法,利用栈,栈中存放到当前括号为止的长度。
左括号放入-1,遇到右括号则在栈中寻找-1,并加上遇见的所有>0的数
int longestValidParentheses(string s) {
vector<int> lstack;
int maxl = 0, index = 0;
while (index < s.size())
{
if (s[index++] == '(')//(则在栈中加-1
lstack.push_back(-1);
else
{
int curl = 0;
while (!lstack.empty())//在栈中寻找第一个为-1的值--匹配)
{
if (lstack.back() == -1)
{
curl += 2;
lstack.pop_back();
//加上之前的:()()这种情况
while (!lstack.empty() && lstack.back() > 0)
{
curl += lstack.back();
lstack.pop_back();
}
maxl = max(maxl, curl);
lstack.push_back(curl);
break;
}
//加上里面的:(())这种情况
curl += lstack.back();
lstack.pop_back();
}
}
}
return maxl;
}