Leetcode热题100-32 最长有效括号
1. 题目描述
2. 解题思路
动态规划
定义状态:
- 设
dp[i]
表示以位置i
结尾的最长有效括号子串的长度。
状态转移方程:
遍历字符串 s
,当遇到 s[i] == ')'
时,存在以下两种情况:
- 情况 1:
s[i - 1] == '('
- 当前字符
')'
与前一个字符'('
组成了一对匹配的括号。 - 更新状态:
d p [ i ] = ( i ≥ 2 ? d p [ i − 2 ] : 0 ) + 2 dp[i] = (i \geq 2 ? dp[i - 2] : 0) + 2 dp[i]=(i≥2?dp[i−2]:0)+2
- 当前字符
- 情况 2:
s[i - 1] == ')'
- 需要满足条件:
i - dp[i - 1] > 0
,即前面存在可以与当前')'
匹配的'('
。
d p [ i ] = ( i − d p [ i − 1 ] ≥ 2 ? d p [ i − d p [ i − 1 ] − 2 ] : 0 ) + d p [ i − 1 ] + 2 dp[i] = (i - dp[i - 1] \geq 2 ? dp[i - dp[i - 1] - 2] : 0) + dp[i - 1] + 2 dp[i]=(i−dp[i−1]≥2?dp[i−dp[i−1]−2]:0)+dp[i−1]+2 - 其中:
dp[i - dp[i - 1] - 2]
表示与当前匹配的'('
前面的有效子串长度(若存在,否则为 0)。dp[i - 1]
是前一个位置的最长有效子串长度。s[i - dp[i - 1] - 1]
与s[i]
匹配(长度为 2)。
- 需要满足条件:
更新最大值:
在遍历过程中,更新最大长度:
maxLen = max ( maxLen , d p [ i ] ) \text{{maxLen}} = \max(\text{{maxLen}}, dp[i]) maxLen=max(maxLen,dp[i])
遍历结束后,maxLen
即为所求结果。
栈解法
初始化:
- 使用一个栈
stk
存储索引。 - 将
-1
压入栈,表示最后一个未匹配的右括号的索引。
遍历字符串:
- 遍历字符串中的每个字符:
- 如果当前字符为
'('
,将其索引压入栈。 - 如果当前字符为
')'
:- 弹出栈顶元素,表示尝试匹配最近的
'('
。 - 如果栈为空,说明没有匹配的
'('
,将当前索引压入栈。 - 如果栈不为空,计算当前有效括号的长度,并更新最大长度
maxLen
:
maxLen = max ( maxLen , i − stack.top() ) \text{{maxLen}} = \max(\text{{maxLen}}, i - \text{{stack.top()}}) maxLen=max(maxLen,i−stack.top())
- 弹出栈顶元素,表示尝试匹配最近的
- 如果当前字符为
3. 代码实现
动态规划
cpp
class Solution {
public:
// 使用栈来解决问题
int longestValidParentheses(string s) {
int maxLen = 0;
int n = s.size();
vector<int> dp(n, 0);
// 注意到子串是指字符串中连续的字符序列
for (int i = 1; i < n; i++) {
if (s[i] == ')') {
// 直接匹配
if (s[i - 1] == '(') {
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
}
// s[i-1]=')'
else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') {
// dp[i-dp[i-1]-2]表示与dp[i-1]相连的有效子字符串的长度
// dp[i]由三部分组成
// s[i-dp[i-1]-1]与s[i]匹配(长度为2)
// dp[i - 1]
// dp[i - dp[i - 1] - 2]或者为0
dp[i] = (i - dp[i - 1] >= 2 ? dp[i - dp[i - 1] - 2] : 0) +
dp[i - 1] + 2;
}
}
maxLen = max(maxLen, dp[i]);
}
return maxLen;
}
};
栈解法
cpp
class Solution {
public:
int longestValidParentheses(string s) {
int res=0;
stack<int> stk;
stk.push(-1);
for(int i=0;i<s.size();i++){
if(s[i]=='('){
stk.push(i);
}else{
stk.pop();
if(stk.empty()){
stk.push(i);
}else{
res=max(res,i-stk.top());
}
}
}
return res;
}
};