Leetcode热题100-32 最长有效括号

Leetcode热题100-32 最长有效括号

1. 题目描述

32 最长有效括号

2. 解题思路

动态规划

定义状态:

  • 设 dp[i] 表示以位置 i 结尾的最长有效括号子串的长度。

状态转移方程:

遍历字符串 s,当遇到 s[i] == ')' 时,存在以下两种情况:

  1. 情况 1:s[i - 1] == '('
    • 当前字符 ')' 与前一个字符 '(' 组成了一对匹配的括号。
    • 更新状态:
      d p i = ( i ≥ 2 ? d p i − 2 : 0 ) + 2 dpi = (i \geq 2 ? dpi - 2 : 0) + 2 dpi=(i≥2?dpi−2:0)+2
  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 dpi = (i - dpi - 1 \geq 2 ? dpi - dp\[i - 1 - 2] : 0) + dpi - 1 + 2 dpi=(i−dpi−1≥2?dpi−dp\[i−1−2]:0)+dpi−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}}, dpi) maxLen=max(maxLen,dpi)

遍历结束后,maxLen 即为所求结果。

栈解法

初始化:

  • 使用一个栈 stk 存储索引。
  • 将 -1 压入栈,表示最后一个未匹配的右括号的索引。

遍历字符串:

  • 遍历字符串中的每个字符:
    1. 如果当前字符为 '(',将其索引压入栈。
    2. 如果当前字符为 ')':
      • 弹出栈顶元素,表示尝试匹配最近的 '('。
      • 如果栈为空,说明没有匹配的 '(',将当前索引压入栈。
      • 如果栈不为空,计算当前有效括号的长度,并更新最大长度 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;
    }
};
相关推荐
dtq04247 小时前
C++小案例 - 日志实战
开发语言·c++
码匠许师傅8 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅9 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
小蒋观天下10 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
WBluuue12 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂12 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode
澳鹏Appen13 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
必须得开心呀13 小时前
字节序大小端科普
c++·程序人生
benjormin13 小时前
Java数据结构 二叉搜索树
数据结构·算法