Leetcode 32. 最长有效括号

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

示例 1:

输入: "(()"

输出: 2

解释: 最长有效括号子串为 "()"

示例 2:

输入: ")()())"

输出: 4

解释: 最长有效括号子串为 "()()"

**难度**: Hard

**标签**: 字符串、 动态规划、


# -*- coding: utf-8 -*-
# @Author  : LG

"""
执行用时:52 ms, 在所有 Python3 提交中击败了86.20% 的用户
内存消耗:14.7 MB, 在所有 Python3 提交中击败了5.47% 的用户

解题思路:
    动态规划
    ))()))(()()))((

    对于 i = ( ,dp[i] = 0
    对于 i = ) ,需要看前面一个
        如果 dp[i-1] 为0 ,则需看s[i-1]
            若s[i-1] = ( ,则匹配, 当前与前一个括号匹配,长度为2, 然后还需要看 i-2 是否是匹配的括号
                dp[i] = dp[i-2] + 2
            否则
                dp[i] = 0
        如果 dp[i-1] 不为0,则前面存在匹配的括号,此时,需查看 s[i-1-dp[i-1]]处字符,也就是前面匹配好的字符的前一个是很么括号
            若s[i-1-dp[i-1]] = (, 则匹配,
                dp[i] = dp[i-2-dp[i-1]] + 2 + dp[i - 1]
            否则
                dp[i] = 0

    在上述过程中,需判断 列表索引是否<0
"""
class Solution:
    def longestValidParentheses(self, s: str) -> int:
        n = len(s)
        if n == 0:
            return 0

        dp = [[] for _ in range(n)]
        dp[0] = 0

        for i in range(1, n):
            if s[i] == '(':
                dp[i] = 0
            else:
                if dp[i - 1] == 0:  # 前一个字符是 ( 或 )
                    if s[i-1] == '(':   # 前一个字符是 (
                        if i - 2 > 0:   # 这里需要进行索引判断
                            dp[i] = 2 + dp[i - 1 - 1]
                        else:
                            dp[i] = 2
                    else:           # 前一个字符是 ), 不匹配
                        dp[i] = 0
                else:
                    if i - 1 - dp[i - 1] >= 0:  # 索引判断
                        if s[i - 1 - dp[i - 1]] == '(': # 匹配好的字符串前一个字符是 (
                            if i - 2 - dp[i - 1] > 0:
                                dp[i] = dp[i - 1] + 2 + dp[i - 1 - dp[i - 1] - 1]
                            else:
                                dp[i] = dp[i - 1] + 2
                        else:                           # 匹配好的字符串前一个字符是 )
                            dp[i] = 0
                    else:
                        dp[i] = 0
        return max(dp)

"""
另附一份精简后的代码
"""
class Solution:
    def longestValidParentheses(self, s: str) -> int:
        n = len(s)
        if n == 0:
            return 0

        dp = [[] for _ in range(n)]
        dp[0] = 0

        for i in range(1, n):
            if s[i] == ')' and i - 1 - dp[i - 1] >= 0 and s[i - 1 - dp[i - 1]] == '(':
                if i - 2 - dp[i - 1] > 0:
                    dp[i] = dp[i - 1] + 2 + dp[i - 1 - dp[i - 1] - 1]
                else:
                    dp[i] = dp[i - 1] + 2
            else:
                dp[i] = 0
        return max(dp)