📌  相关文章
📜  最长平衡子序列的长度(1)

📅  最后修改于: 2023-12-03 15:26:28.714000             🧑  作者: Mango

最长平衡子序列的长度

最长平衡子序列的长度问题是一个典型的动态规划问题,其难点在于设计状态和状态转移方程。

问题描述

给定一个仅包含 '(' 和 ')' 两种字符的字符串 s,找出最长连续的平衡子序列,返回该子序列的长度。平衡子序列是指在该子序列中, '(' 和 ')' 的数量相等。

解法
思路

我们可以定义 $dp[i]$ 为以第 $i$ 个字符为结尾的最长连续平衡子序列长度。注意,这里子序列需要连续,也就是说,$dp[i]$ 表示以第 $i$ 个字符为结尾的平衡子序列的长度。

状态转移方程如下:

  • 当 $s[i]$ 为 '(' 时,无法构成平衡子序列,因此 $dp[i]=0$。
  • 当 $s[i]$ 为 ')' 时,有两种情况:
    • 若 $s[i-1]$ 为 '(',则可以构成一对平衡括号,此时 $dp[i]=dp[i-2]+2$。
    • 若 $s[i-1]$ 为 ')',则需要判断是否存在以 $s[i-1]$ 结尾的平衡子序列,即判断 $i-dp[i-1]-1$ 是否为 '('。如果是,那么可以将以 $s[i-1]$ 结尾的平衡子序列与当前的 $'$ )'$ 构成平衡子序列,此时 $dp[i]=dp[i-1]+dp[i-dp[i-1]-2]+2$。

最终答案为 $\max{dp}$。

代码
def longest_balanced_subsequence(s: str) -> int:
    n = len(s)
    dp = [0] * n
    res = 0
    for i in range(1, n):
        if s[i] == '(':
            dp[i] = 0
        else:
            if s[i-1] == '(':
                dp[i] = dp[i-2] + 2
            elif i-1-dp[i-1] >= 0 and s[i-1-dp[i-1]] == '(':
                dp[i] = dp[i-1] + dp[i-2-dp[i-1]] + 2
            res = max(res, dp[i])
    return res
复杂度分析
  • 时间复杂度:$O(n)$,其中 $n$ 为字符串 $s$ 的长度。需要遍历每个字符并更新状态。
  • 空间复杂度:$O(n)$,需要使用 $dp$ 数组来存储状态。