zoukankan      html  css  js  c++  java
  • 32. Longest Valid Parentheses

    问题:

    给定由 "(" 和 ")" 构成的字符串,

    求其中完全匹配的子串,最长长度为多少。

    Example 1:
    Input: s = "(()"
    Output: 2
    Explanation: The longest valid parentheses substring is "()".
    
    Example 2:
    Input: s = ")()())"
    Output: 4
    Explanation: The longest valid parentheses substring is "()()".
    
    Example 3:
    Input: s = ""
    Output: 0
    
    Constraints:
    0 <= s.length <= 3 * 104
    s[i] is '(', or ')'.
    

    解法:DP(动态规划)

    1.确定【状态】:字符串s的

    • 第i个字符:s[i]

    2.确定【选择】:分两种情况

    • s[i] == '(':
      • 任何以'('为结尾的字符串,都不可能是匹配字符串,因此:dp[i]=0
    • s[i] == ')':
      • 若前面串中存在多余出来的 '(' (open>0)那么这里匹配到一对括号:dp[i]=dp[i-1]+2
      • 同时,若此时dp[i]得到的匹配子串长度<子串总长度 i,需要追加前面的匹配结果:dp[i]+=dp[i-dp[i]]
        • 解释:到当前为止的字符串:s[ 0i-dp[i]i ]
        • 在当前直前的子串 i-dp[i] ~ i 中,我们已得到结果:dp[i]=dp[i-1]+2
        • 在这再前一个子串 0 ~ i-dp[i] 中,若有匹配好的(以i-dp[i]为结尾的)子串,我们则须将这一段也追加入当前结果中:dp[i]+=dp[i-dp[i]]

    3. dp[i][j]的含义:

    字符串s,到第 i 个字符为止,包含最后一个字符s[i]在内,最长匹配子串的长度。

    4. 状态转移:

    dp[i]=

    • (s[i] == '('):= 0 (open++)
    • (s[i] == ')') && open>0:=
      • 上一个包含s[i]字符的状态:dp[i-1]+2
      • + 当前满足条件子串直前的字符串的结果 dp[i-dp[i]]
      • (open--)

    5. base case:

    • dp[0]=0
    • dp[1]=0

    对于本问题所求,则将以各个字符(包含该字符)为止,最长满足条件匹配子串长度,求最大值。

    res = max(res, dp[i]);
    

    代码参考:

     1 class Solution {
     2 public:
     3     //dp[i]: s[0~i], && s[i]included, the length of the parentheses substring.
     4     //state: index i
     5     //opt:
     6     // s[i]=='(': dp[i]=0 (against:&& s[i]included)
     7     // s[i]==')': if opened(previous contained "("), dp[i]=dp[i-1]+2
     8     //            if dp[i](substring len)< i(all str len), dp[i]+=dp[i-dp[i]]; add previous result
     9     //base: dp[0] = 0,
    10     //      dp[1] = 0
    11     int longestValidParentheses(string s) {
    12         int res = 0;
    13         int open = 0;
    14         vector<int> dp(s.size(), 0);
    15         for(int i=0; i<s.size(); i++) {
    16             if(s[i]=='(') {
    17                 open++;
    18                 dp[i]==0;
    19             } else if(s[i]==')' && open>0) {//')'
    20                 open--;
    21                 dp[i] = dp[i-1]+2;
    22                 if(dp[i]<i) dp[i]+=dp[i-dp[i]];
    23             }
    24             res = max(res, dp[i]);
    25         }
    26         return res;
    27     }
    28 };
  • 相关阅读:
    C#中添加文本框的上标及文字大小
    综采工作面设备接替计划管理系统
    一位年轻女董事长的27条忠告
    开发人员一定要加入收藏夹的网站
    哈佛图书馆墙上的名训
    加密、解密.NET字符串
    C#文件上传下载
    DotNetNuke3.0.8 简体中文语言包(可直接导入版)发布
    DNN的Core Team
    DotNetNuke3.0.8文件管理器的错误及解决方法
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14566427.html
Copyright © 2011-2022 走看看