【LeetCode】32. 最长有效括号

本文介绍了解决最长有效括号子串问题的两种高效算法:栈和动态规划。通过示例说明了如何找出给定字符串中包含有效括号的最长子串长度,提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

示例 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

 

方法一:栈

用栈 p 存储还未匹配的 ( 的下标,flag 用来标记 ( 的位置;

当 s[ i ] 为 ( 时,直接入栈;

当 s[ i ] 为 ) 时,若栈为空,flag = i + 1,前面的都作废,若栈不空,pop( ),匹配 ( ;

匹配后,若栈为空,求长度,res = i - flag + 1;

若栈不空,求长度,res = i - p.top( )(这个下标的 ( 还未出栈,少加 1 )!

class Solution {
public:
    int longestValidParentheses(string s) {
        int res = 0;
        int n = s.size();   
        stack<int> p;
        int flag = 0;
        for(int i=0; i<n; i++){
            if(s[i] == '('){
                p.push(i);
            }else{
                if(p.empty())
                    flag = i + 1;
                else{
                    p.pop();
                    if(p.empty())
                        res = max(res, i-flag+1);
                    else
                        res = max(res, i-p.top());
                }
            }
        }
        return res;
    }
};

 

方法二:动态规划

dp[ i ] 表示以 i 下标符号为结尾的最长有效括号长度。

若当前符号为 ' ( ',dp[ i ] 肯定为 0;若当前符号为 ' ) ',则分两种情况:

1)s[i - 1] 为 ' ( ' 时,dp[ i ] = dp[i - 2] + 2;

2)s[i - 1 - dp[i - 1]] 为 ' ( ' 时(跳过 dp[i - 1] 长度找再前一个的符号),dp[ i ] = dp[i - 1] + 2 + dp[ i - 2 - dp[i - 1]],注意不要忘记再前面的 dp[ i - 2 - dp[i - 1]] 可能匹配成功的有效括号长度。

res 保存最大值,每次计算完 dp 后更新最大值。

class Solution {
public:
    int longestValidParentheses(string s) {
        if(s.empty())
            return 0;
        int res = 0;
        int n = s.size();   
        vector<int> dp(n,0);
        if(s[0] == '(' && s[1] == ')')
            dp[1] = 2;
        res = max(res,dp[1]);
        for(int i=2; i<n; i++){
            if(s[i] == '(')
                dp[i] = 0;
            else{
                if(s[i-1] == '(')
                    dp[i] = dp[i-2] + 2;
                else if(s[i-1-dp[i-1]] == '(')
                    dp[i] = dp[i-1] + 2 + dp[i-2-dp[i-1]];
            }
            res = max(res,dp[i]);
        }
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值