问题链接
LeetCode 32. Longest Valid Parentheses
题目解析
给出只包含左右括号的字符串,返回最长的括号匹配字符串长度。
解题思路
括号匹配问题一般借助 栈,便于理解。定义 \(start\) 记录合法字符串的起始位置,遍历字符串:
- 当遇到左括号,则把其索引压入栈中;
- 当遇到右括号,判断栈是否为空,若为空,说明当前右括号无法匹配,则需要更新合法开始位置为i+1,不为空,说明可以匹配,可以匹配的情况下,先弹出栈顶元素,这时候再次判断栈是否为空,若为空,则更新结果为和 \((i-start+1)\) 中的较大值,否则更新结果为和 \((i-LVP.top()+1)\) 的最大值。
参考代码
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> LVP;
int res = 0, start = 0;
for(int i = 0; i < s.length(); i++) {
if(s[i] == '(') LVP.push(i);
else {
if(LVP.empty()) start = i+1;
else {
LVP.pop();
if(LVP.empty()) res = max(res, i-start+1);
else res = max(res, i-LVP.top());
}
}
}
return res;
}
};
动态规划解法
本题也可以使用动态规划求解,参考:[LeetCode] Longest Valid Parentheses。个人认为该博主讲的不是很清楚,这里再简单说两句。
定义DP[i]为以 \(s[i-1]\) 结尾的LVP。
- 对于 s[i-1]==‘(‘,则 DP[i]=0;
- 对于 s[i-1]==‘)‘,我们找到以s[i-2]结尾的LVP的开始位置.
举个例子:对于字符串···( xxxx )···,其中xxxx代表以s[i-2]结尾的LVP,要找的即是例子中左括号的索引,怎么求呢?很简单,\(left = i-2-DP[i-1]\)。
请注意DP数组的定义:以 \(s[i-1]\) 结尾的LVP。需要判断一些特殊情况,只有在 \(s[i-1]==')' && left >= 0 && s[left] == '('\) 时,才可以更新 \(DP[i] = DP[i-1]+2+DP[left]\)。
参考代码如下:
class Solution {
public:
int longestValidParentheses(string s) {
vector<int> DP(s.length()+1, 0);
int maxLen = 0;
for(int i=1; i <= s.length(); i++) {
int left = i-2-DP[i-1];
if(s[i-1]=='(' || left<0 || s[left]==')')
DP[i] = 0;
else {
DP[i] = DP[i-1]+2+DP[left];
maxLen = max(maxLen, DP[i]);
}
}
return maxLen;
}
};
官方解法
官方题解:32. Longest Valid Parentheses。其中提到了四种方法,本文中讲到的是第二第三种方法,另外最后还有一种空间O(1)的方法,比较巧妙。
相似题目
LeetCode 20. Valid Parentheses
LeetCode 22. Generate Parentheses
LeetCode All in One题解汇总(持续更新中...)
本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.