leetcode32 最长有效括号(Hard)

题目来源:leetcode32 最长有效括号

题目描述:

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

示例 1:

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

示例 2:

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

解题思路:

参考题解
使用动态规划,dp[i]定义为:以s[i]为结尾的子串中,形成的最长有效子串的长度。dp[0]=0。

  1. 如果s[i]是')',判断s[i-1]
    ① s[i-1]是'('
    如果i-2>=0 ,那么dp[i]=dp[i-1]+2;否则dp[i]=2;
    ②s[i-1]是')'
    以s[i-1]为结尾形成的最长有效长度为dp[i-1],跨过这个长度(里面细节不用管,总之它最大能提供dp[i-1]长度),来看s[i-dp[i-1]-1]这个字符:
    s[i-dp[i-1]-1]不存在或为')',s[i]找不到匹配,直接gg,dp[i] = 0
    s[i-dp[i-1]-1]是'(',它和s[i]呼应,有效长度 2 保底,加上跨过的dp[i-1],再加上前方的dp[i-dp[i-1]-2]…等等…s[i-dp[i-1]-2]要存在才行
    s[i-dp[i-1]-2]存在,dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2
    s[i-dp[i-1]-2]不存在,dp[i] = dp[i-1] + 2

  2. 如果s[i]是'(',不能构成有效子串,dp[i]=0;

class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.size();
        vector<int> dp(n,0);
        int ans=0;
        for(int i=1;i<n;i++){
            if(s[i]==')'){
                if(s[i-1]=='('){
                    if(i-2>=0) dp[i]=dp[i-2]+2;
                    else dp[i]=2;
                }
                else {
                    if(i-dp[i-1]-1>=0&&s[i-dp[i-1]-1]=='('){
                        if(i-dp[i-1]-2>=0)
                            dp[i]=dp[i-dp[i-1]-2]+dp[i-1]+2;
                        else dp[i]=dp[i-1]+2;
                    } 
                }
            }
            else dp[i]=0;
            ans=max(ans,dp[i]);
        }
        return ans;
    }
};
原文地址:https://www.cnblogs.com/yjcoding/p/13287937.html