BM77 最长的括号子串(python)

题目

题目链接

给出一个长度为 n 的,仅包含 ‘(’ 和 ‘)’ 的字符串,计算最长的格式正确的括号子串的长度
在这里插入图片描述

动态规划

使用一个长度与字符串相等的dp数组,初始化为全0,每个元素表示:以字符串中当前位置结尾的正确括号子串长度,则有:

  • 合法的括号子串一定以)结尾,但以)结尾的不一定合法

  • 如果当前位置i处的字符为(,一定不合法,dp[i]=0

  • 若当前位置i处的字符为),检查它前一个字符,则有2种情况:
    1)形如(),则此处dp值为dp[i-2]+2
    2)形如)),则对i处的)即第二个)来说,它的前面可能有合法的括号子串,长度为dp[i-1]
    ①若该合法的括号子串前面无(,则此处的)为多余的右括号,此处dp值为0
    ②若该合法的括号子串前面恰好有一个(,则可以形成(...)的形式,该段(...)长度为dp[i-1]+2;考虑到前面这个左括号前还可能有合法的括号子串,所以i处的dp值还需要再加上dp[i - dp[i - 1] - 2]
    得到该情况下的状态转移方程为:

dst[i] = dst[i] + dst[i - 1] + 2 + dst[i - dst[i - 1] - 2]

注意防止坐标越界:检查前面的合法子串前是否有(时,要检查i - dst[i - 1] - 1是否>=0;在检查(…)前面是否还有合法子串时,要检查i - dst[i - 1] - 2 是否>= 0

代码

class Solution:
    def longestValidParentheses(self, s):
        if not s:
            return 0
        dst = [0] * len(s)  # dst中元素表示以当前下标结尾的最长的括号子串长度
        # 合法的括号子串一定以)结尾,长度为偶数
        # 每次检查当前字符和前一个字符
        for i in range(1, len(s)):
            # (结尾,一定不是合法括号子串,dp值为0
            if s[i] == '(':
                continue
            # 形如(),则dp值为2格前的dp值+2
            elif s[i - 1] == '(' and s[i] == ')':
                if i == 1:
                    dst[i] += 2
                else:
                    dst[i] = dst[i - 2] + 2
            # 形如)),则跳过中间的合法子串,看前面是否是(
            elif s[i - 1] == ')' and s[i] == ')':
                if i - dst[i - 1] - 1 >= 0 and s[i - dst[i - 1] - 1] == '(':
                    dst[i] = dst[i - 1] + 2
                    # 看(前面是否还有合法子串
                    if i - dst[i - 1] - 2 >= 0:
                        dst[i] += dst[i - dst[i - 1] - 2]
        return max(dst)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值