zoukankan      html  css  js  c++  java
  • 193 最长有效括号

    原题网址:https://www.lintcode.com/problem/longest-valid-parentheses/my-submissions

    描述

    给出一个只包含'(' 和')'的字符串,找出其中最长的左右括号正确匹配的合法子串。
     

     

     

    正确理解题目很重要……

    比如对字符串“()((())”,最长有效括号子串为“(())”,输出应该是4

    方法一:动态规划

    设dp数组为以当前字符作为结尾的最长有效括号子串长度(注意dp[i]与dp[i-1]不是简单的累加关系,dp[i]也不是前i个字符串中最长有效括号长度),

    所以如果当前字符是‘(’,dp值为0。如果当前字符是‘)’,有两种情况:

    1.前一个字符是‘(’,前一个字符与当前字符刚好匹配,则dp[i] = dp[i - 2] + 2 ;

    2.前一个字符是‘)’,这时要判断以前一个右括号为尾的最长有效括号之前的一个字符是否是左括号(,

    如果是左括号,即“…((…))”,则dp[i]应该等于它和它对应左括号中间的有效括号数dp[i−1]加现在的两个,再加对应左括号之前的最长有效括号数dp[i−dp[i−1]−2],即dp[i]=dp[i−1]+dp[i−dp[i−1]−2]+2;

    如果是右括号,即“…)(…))”,则dp[i]是0.

    最后,因为dp[i]只是当前字符结尾的最长有效括号子串长度,所以需要用一个全局最长长度与每次更新的dp[i]对比。

    注意数组越界的判断。

    代码:

    int longestValidParentheses(string &s) {
        // write your code here
        if(s.length()==0) return 0;
        int maxLen = 0;
        vector<int> dp(s.length(),0);
    
        for(int i = 1; i < s.length(); i++)
        {
            if(s[i] == ')')
            {
                if(s[i-1] == '(')
                {
                    dp[i] = i-2>=0?dp[i-2]+2:2;
                }
                else
                {
                    if(i-dp[i-1]-1 >= 0)
                    {
                        if(s[i-dp[i-1]-1] == '(')
                        {
                            dp[i] = i-dp[i-1]-2>= 0? dp[i-1]+2+dp[i-dp[i-1]-2] : dp[i-1]+2;
                        }
                    }
                }
            }
            if(dp[i] > maxLen)
            {
                maxLen = dp[i];
            }
        }
        return maxLen;
    }

    方法二:

    用两个计数器 left 和 right 。首先,从左到右遍历字符串,遇到 ‘(’,增加 left计数器;遇到 ‘)’ ,增加 right 计数器。每当 left 计数器与 right 计数器相等时,计算当前有效字符串的长度,并且记录目前为止找到的最长子字符串。如果 right计数器比 left 计数器大,将 left和 right 计数器同时变回 0。

    代码:

    int braketstr1(string s)
    {
        if (s.length() == 0 || s.length() == 1)
            return 0;
        int len = s.length();
        int left = 0, right = 0;
        int braketmax = 0;
        for(int i=0;i<len;i++)
        {
            if (s[i] == '(')
                left++;
            else
                right++;
            if (right == left)
                braketmax = braketmax > (2 * right) ? braketmax : 2 * right;
            else if (right > left)
            {
                right = 0;
                left = 0;
            }
        }
        return braketmax;
    }

    参考:

    1.https://blog.csdn.net/ysl_ysl123/article/details/93714147

    2.https://www.cnblogs.com/ycw1024/p/11322099.html

  • 相关阅读:
    软件工程课堂作业——计算最优惠价格
    团队项目——NABC
    二位数组
    第二次冲刺阶段 站立会议06
    第二阶段冲刺 站立会议05
    第二阶段冲刺 站立会议04
    第二阶段冲刺 站立会议03
    课程建议
    站立会议02
    第二阶段冲刺 站立会议01
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/13460385.html
Copyright © 2011-2022 走看看