32. 最长有效括号

Posted 2016bits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了32. 最长有效括号相关的知识,希望对你有一定的参考价值。

一、题目描述

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

二、实例

示例 1:

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

示例 2:

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

示例 3:

输入:s = ""
输出:0

补充示例 4:

输入:s = "(()())"
输出:6

补充示例 5:

输入:s = "((()))"
输出:6

三、输入输出说明

0 <= s.length <= 3 * 104
s[i] 为 '(' 或 ')'

四、基本思路

1、栈

遇到左括号则进栈,遇到右括号则出栈。由于统计最长有效括号,所以形如"()()"这种,会经历连续两次进栈出栈,则设置start记录最开始的位置。在这种情况下,遇到左括号进栈无影响,遇到右括号出栈则需要分情况讨论:

若出栈之前栈内已无元素,则更新start为当前位置的下一位置,最长序列长度不变;

若出栈时栈内有元素,则先出栈,若出栈之后栈内无元素,则当前序列长度为start与当前索引之间的距离(i - start + 1)(此时序列长度包含start位置的元素,所以需要+1),同时更新最长序列长度

若出栈之后栈内仍有元素,则当前序列长度为栈顶元素st.top()与当前索引之间的距离(i - st.top())(此时序列长度不包含栈顶元素,所以不需要+1),同时更新最长序列长度

2、动态规划

使用动态规划时主要需要考虑后续问题如何利用之前问题的解,在本问题中则需要考虑如何增长有效括号的长度。主要分为以下两种情况:(使用数组dp[i]记录从第一个符号到索引为i位置处最长有效括号的长度)

  • "(())":当i为0和1处的dp[i]均为0,到达索引为i=2的位置,由于i-1处为左括号,i处为右括号,此时可以增长有效括号长度:dp[i] = dp[i-1] + 2(前一位置的最长长度加上新增的括号对,长度加2)。当索引i=3时同样适用。
  • "()()":此时为括号并列的情况,此时需要寻找在匹配了当前右括号(i=3)的左括号(i=2)的前一位置(i=1),若此位置存在,则加上该位置(i=1)的最长长度:dp[i] += dp[i - 1 - dp[i-1] - 1](对比示例仔细考虑索引关系)

五、代码

1、栈

class Solution 
public:
    int longestValidParentheses(string s) 
        if (s == "") 
            return 0;
        
        int start = 0;
        int ans = 0;
        stack<int> st;
        for (int i = 0; i < s.length(); i++) 
            if (s[i] == '(') 
                st.push(i);
            
            else if (st.empty()) 
                start = i + 1;
                continue;
            
            else 
                st.pop();
                if (st.empty()) 
                    ans = max(ans, i - start + 1);
                
                else 
                    ans = max(ans, i - st.top());
                
            
        
        return ans;
    
;

2、动态规划

class Solution 
public:
    int longestValidParentheses(string s) 
        if (s == "") 
            return 0;
        
        int ans = 0;
        int len = s.length();
        int* dp = new int[len]();//创建长度为s.length(),初始值为0的数组
        for (int i = 1; i < len; i++) 
            int left = i - 1 - dp[i-1];
            if (s[i] == ')' && left >= 0 && s[left] == '(') 
                dp[i] = dp[i-1] + 2;
                if (left - 1 >= 0) 
                    dp[i] += dp[left-1];
                
            
            ans = max(ans, dp[i]);
        
        return ans;
    
;

 

以上是关于32. 最长有效括号的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-32-最长有效括号

32. 最长有效括号

32.最长有效括号(Longest Valid Parentheses)

32.最长有效括号(Longest Valid Parentheses)

Leetcode(32)-最长有效括号

leetcode32 最长有效括号(Hard)