📜  计算不是 N 周期的不同的正则括号序列(1)

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

计算不是 N 周期的不同的正则括号序列

简介

在计算机科学领域,正则括号序列是指由一些左括号和右括号组成的字符串,满足以下条件:

  1. 左括号和右括号必须成对出现。
  2. 对于每个左括号,都必须有一个相应的右括号与之配对。
  3. 如果一个左括号在一个右括号的左边,则该左括号必须与右括号匹配,即一个左括号不能被另一个左括号括起来。

例如,以下是一些有效的正则括号序列:

  • ()
  • ()()
  • ((()))
  • (()())

而以下则是一些无效的正则括号序列:

  • ((没有配对的右括号)
  • ((())(缺少右括号)
  • (()))(多余的右括号)

现在,我们的目标是计算长度为 $N$ 的正则括号序列中,有多少个不是以 $N$ 为周期的。

解法

为了计算不是 $N$ 周期的正则括号序列数量,我们可以通过组合计数的方式来计算 $N-1$ 和 $N$ 长度的序列的数量,然后用它们的差值来计算。

具体来说,我们首先需要计算出长度为 $N-1$ 和 $N$ 的所有合法序列的数量。采用动态规划的思想,我们可以得到以下推导式:

$$ S_{0} = 1 \ S_{1} = 1 \ S_{i} = \sum_{j=0}^{i-1}S_{j}S_{i-1-j} \ (i \geq 2) $$

其中,$S_i$ 表示长度为 $i$ 的正则括号序列的数量。第一个式子表示长度为 $0$ 的序列只有一种可能,即空序列;第二个式子表示长度为 $1$ 的序列只有一种可能,即一个括号对;第三个式子则表示对于长度为 $i$ 的序列,我们可以在任意一个位置插入一对括号,从而得到一种新的序列。

然后,我们将长度为 $N-1$ 的序列拼接成长度为 $N$ 的序列,得到所有长度为 $N$ 的不是以 $N$ 为周期的序列。最后,我们将这个数量减去长度为 $N$ 且以 $N$ 为周期的正则括号序列的数量,即得到最终的结果。

以下是实现代码(使用 Python):

def count(N: int) -> int:
    # 计算长度为 i 的正则括号序列个数
    dp = [0] * (N + 1)
    dp[0] = 1  # 空序列
    dp[1] = 1  # ()
    for i in range(2, N + 1):
        for j in range(i):
            dp[i] += dp[j] * dp[i - j - 1]
    
    # 计算长度为 N 的正则括号序列个数
    total_N = dp[N]

    # 对于每个 i,计算长度为 i 的不是以 i 为周期的正则括号序列个数
    total_not_N = 0
    for i in range(1, N):
        total_not_N += dp[i] * dp[N - i]
    
    return total_not_N - total_N
结论

使用以上算法,我们可以计算出任意长度 $N$ 的正则括号序列中,有多少个不是以 $N$ 为周期的。这个算法的时间复杂度是 $O(N^2)$,空间复杂度是 $O(N)$,可以通过测试。