ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode-32.最长有效括号

2022-06-26 08:31:25  阅读:133  来源: 互联网

标签:字符 括号 int 32 有效 长度 leetcode dp


题目:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 动态规划的详细思路和推倒过程写在注释了

class Solution {
public:
    int longestValidParentheses(string s) {
        int max = 0; 
        int N = s.size();
        if ( N < 2) {
            return 0;
        }
        // 为了理解动态规划的思路,我们按照 暴力求解 --> 动态规划的过程
        // 首先,我们知道,最终的最长有效括号,一定是以字符串s的某个位置为结尾,但是这个位置是不固定的
        //  1. 暴力求解
        //     很自然,我们就会想到,我们把以字符串s的每个位置为结尾的有效括号全部找出来,然后在所有的有效括号中找出最长 的就得到答案了
        //  2. 对暴力求解的分析
        //      如果分析暴力求解的所有结果,就会发现,对于某一个位置i而言,我们会把它所有有效括号都找出来,但是我们需要的是最长的那个,
        //      比如对于字符串"()()"的最后一个位置,我们可以找出两个有效括号由s[2]和s[3]构成的2个长度的(),以及由s[0]s[1]s[2]s[3]构成的4个长度的()(),而我们其实只需要由s[0]s[1]s[2]s[3]构成的,然后我们将以每个位置为结尾的最大有效括号长度做对比,取出最大的那个,就是答案
        //    因此从这个角度看,我们定义dp[N], dp[i]其含义为以字符i结尾的(必须包含i位置字符)的最大有效括号长度
        //    基于这个定义,我们最终要返回的是dp[N]中的最大值,而不是dp[N-1]
        //    很多同学没有理解这个dp数组含义,把以字符i结尾的最大有效括号长度,等同于了”到字符i为止的字符串所包含最大有效括号长度“,导致dp数组无法递归下去
        //    因为如果按照错误的理解,对于字符串 ”(())(“那么就会想返回dp[N-1],
        //    就会得到这样的dp数组, dp[0] = 0; dp[1]=0, dp[2]=2,dp[3]=4,dp[4]=4, 请注意dp[4], 按照错误的定义的话,dp[4]是应该等于4,因为它自己虽然不能构成新的有效括号,但是它前面的括号已经构成了4个长度的括号,到s[4]为止的字符串,至少是有4个长度的括号的,因此dp[4]=4,
        //    然而一旦误入这个解释,就会发现无法解决各种括号的匹配问题,怎么也递归不下去到dp[N-1]
        //    因此强调一下, dp[i]其含义为以字符i结尾的(必须包含i位置字符)的最大有效括号长度, 而不是”到字符i为止的字符串所包含最大有效括号长度“

        std::vector<int> dp (N, 0);
        for ( int i = 1; i < N ; i++ ) {
            if ( s[i] != ')' ) {
                continue;
            }
            int pre = i - dp[i-1] - 2; 
            // 说明当前位置的字符s[i]=')', 且s[i-1]='(’, 两者构成有效括号,其长度为dp[i-1]+2
            // 还应该考虑,一旦当前字符和其前一个字符构成有效括号后,它还可能和当前有效括号的前一个有效括号连起来,
            // 构成更长的有效括号
            if ( s[i-1] == '(' ) {
                dp[i] = dp[i-1] + 2;
                if ( pre >= 0) {
                    dp[i] = dp[i] + dp[pre];
                }
            }
            // 如果s[i]的前一个字符不是'(', 则需要判断 s[i] 是否可以和遥远的更左边(i - dp[i-1] -1)构成有效括号
            else {
                int index = i - dp[i-1] -1; 
                // index 越界, 比如())的最后一个字符
                if ( index < 0 ) {
                    dp[i] = 0;
                }
                else if ( s[index] == '(' ) {
                    dp[i] = dp[i-1] + 2; 
                    // 下面代码同之前是一样的含义解决 类似 (())(()) 的最后一个字符的括号长度计算情景
                    if ( pre >=0 ) {
                        dp[i] = dp[i] + dp[pre];
                    }
                }
                else {
                    // 这个代表找到遥远的括号,可惜对方和自己不是一对,无法构成有效口号,比如 )())的最后一个字符
                    dp[i] = 0;
                }  
            }
            max = std::max( max, dp[i] );
        }
        return max;
    }
};

  

标签:字符,括号,int,32,有效,长度,leetcode,dp
来源: https://www.cnblogs.com/houjianli/p/16412923.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有