力扣刷题-32.最长有效括号

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

  1. 动态规划初步
    动态规划可以理解为是一种递归的思想,当前的状态可以由之前已知的状态推导过来 ,用数学表示即:f(x)可以由f(x-1)或者f(x-2)的某种关系得到。
     一般来讲,目标是求什么则什么即为状态,然后分析当前状态和之前状态的推导关系,进而进行穷举所有状态即可。
  2. 解题思路
     用dp[i]表示以i位置字符结尾的最长有效括号的字符串长度,初始化所有状态为0。
     若nums[i] = ‘(’,即以左括号结尾的字符串肯定有效括号长度为0;
     若nums[i] = ‘)’,即右括号结尾可能为有效括号字符串,有效匹配有两种情况:
     ①:和紧挨的前一个位置的左括号匹配,则dp[i] = dp[i-2]+2。
     ②:隔了一段有效括号长度的前一个位置匹配,则dp[i] = dp[i-1]+2+dp[i-dp[i-1]-2]+2
     如下图:
    力扣刷题-32.最长有效括号_第1张图片
  3. 代码示例
class Solution {
public:
    int longestValidParentheses(string s) {
        //dp[i] 表示以位置i结尾的最长有效字符串长度
        int resault = 0;
        if( s.length() < 2) return resault;
        vector<int> dp(s.length(),0);//初始化为0
        dp[0] = 0;
        for( int i = 1;i < s.length();i++)
        {
            if( s[i] == '(')  dp[i] = 0;//左括号结尾肯定无效
            else 
            {
                if( s[i-1] == '(')//i和i-1匹配
                {
                    if( i-2 >= 0)
                        dp[i] = dp[i-2] +2;
                    else 
                        dp[i] = 2;     
                }
                else
                {
                    //往前缩进dp[i-1]的距离的上一个位置是否和当前匹配
                    if( i - dp[i-1] -1 >= 0 )
                    {
                        if( s[ i - dp[i-1] -1] == '(' )
                        {
                            if( i - dp[i-1] -2 >= 0)
                            {
                                dp[i] = dp[i - dp[i-1] -2 ] + 2 + dp[i-1];
                            }
                            else
                                 dp[i] = 2 + dp[i-1];
                        }
                    }
                }
            }
           resault =  resault > dp[i] ? resault:  dp[i];
        }
        return resault;       
    }
};
  1. 其他解法
     具体到本题还可以用栈(stack)来实现,栈是一种先进后出的数据结构。将元素下标入栈,栈底永远为当前可以匹配字符串的前一个位置。遇左括号入栈,右括号则出栈,动态更新当前元素坐标和栈顶元素距离并取最大值即可,本文主要为讨论动态规划的解法,本方法不再详细叙述代码。

你可能感兴趣的:(力扣刷题,#,动态规划)