力扣LeetCode:32. 最长有效括号(Python)(详细题解)

题目描述

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

题解(动态规划)

第一思路是采用动态规划。假设已经有若干长度的有效括号,我们考察括号长度继续增长的两种形式:

  1. xxxx()
  2. (xxxx)

即增加独立的有效括号,或者在外部嵌套一层括号。我们令dp[i]代表以s[i]结尾的最长连续有效括号长度,初始化为0。如果s[i]为左括号,dp[i]=0。如果s[i]为右括号,我们分别讨论上述两种情况:

对于第一种情况,s[i-1]与s[i]分别为左括号与右括号,则有dp[i]=dp[i-2]+2。

对于第二种情况,也就是:①(②)。我们注意到,dp[i-1]表示了内部的有效括号的长度,那么与s[i]匹配的左括号应该是s[i-1-dp[i-1]]。如果二者匹配,则有dp[i] = dp[i-2-dp[i-1]] + dp[i-1] + 2,其中dp[i-2-dp[i-1]]是①的长度,dp[i-1]是②的长度,2是新加的两个括号。

代码(动态规划)

class Solution(object):
    def longestValidParentheses(self, s):
        n = len(s)
        dp = [0 for i in range(n)]
        rs = 0
        for i in range(1, n):
            if s[i] == ')':
                if s[i-1] == '(':
                    dp[i] = dp[i-2] + 2 if i-2 >= 0 else 2
                elif s[i-1] == ')' and i-1-dp[i-1] >= 0 and s[i-1-dp[i-1]] == '(':
                    dp[i] = dp[i-2-dp[i-1]] + dp[i-1] + 2 if i-2-dp[i-1] >= 0 else dp[i-1] + 2
            rs = max(rs, dp[i])
        print(dp)
        return rs

题解(栈)

最为关键的思路是,栈中存储的并不是左右括号字符,而是未匹配的括号的位置。我一开始没有想明白这一点,因此耽误了比较久时间。

我们自左向右遍历字符串中的每一个字符,去检查它能否与栈顶代表的未匹配位置相匹配:

  • 当且仅当栈顶元素所指的字符为左括号、当前字符为右括号时,二者匹配,出栈。新的栈顶所指示的位置与当前位置的差即为有效匹配的长度。我们取遍历过程中的所有长度的最大值,即为最终的最长有效匹配长度。
  • 其他情况下,都不匹配,当前位置入栈。

代码(栈)

class Solution(object):
    def longestValidParentheses(self, s):
        stack = []
        rs = 0
        for i, ch in enumerate(s):
            if stack and ch == ')' and s[stack[-1]] == '(':
                stack.pop()
                rs = max(rs, i - stack[-1] if stack else i + 1)
            else:
                stack.append(i)
        return rs

猜你喜欢

转载自blog.csdn.net/qq_41112170/article/details/128201767