这两道连续编号的算法题来自某编程平台的每日挑战系列,聚焦于"稳定的二进制数组"这一特殊数据结构。所谓稳定的二进制数组,根据题目描述可以推断出需要满足以下两个核心条件:
这类问题在计算机科学中属于典型的组合数学问题,与德布鲁因序列、游程受限编码等概念相关。在实际应用中,稳定的二进制序列常出现在数据编码、通信协议设计等领域,用于确保信号传输的可靠性。
第一题要求我们枚举所有长度为n的稳定二进制数组。对于这类组合枚举问题,常规解法有:
考虑到n的范围(题目未明确,但通常这类问题n≤20),回溯是最直观的解法。其核心思路是:
第二题通常会在第一题基础上增加难度,可能要求:
对于统计问题,动态规划是更优的选择。我们可以定义dp[i][j][k]表示:
状态转移方程需要考虑:
python复制def generate_stable_binary(n):
result = []
def backtrack(path):
if len(path) == n:
result.append(path.copy())
return
for digit in [0, 1]:
if len(path) >= 2 and path[-1] == path[-2] == digit:
continue # 剪枝:避免三个连续相同
path.append(digit)
backtrack(path)
path.pop()
backtrack([])
return result
关键点说明:
python复制def count_stable_binary(n):
if n == 0: return 0
if n == 1: return 2
if n == 2: return 4
# dp[i][j][k]:长度为i,最后是j,连续k个j
dp = [[[0]*3 for _ in range(2)] for __ in range(n+1)]
# 初始条件
dp[1][0][1] = 1
dp[1][1][1] = 1
dp[2][0][1] = 1 # 10
dp[2][0][2] = 0 # 不可能有两个0结尾且连续两个0
dp[2][1][1] = 1 # 01
dp[2][1][2] = 0 # 同上
for i in range(3, n+1):
for j in [0, 1]:
# 当前位与上一位不同
other = 1 - j
dp[i][j][1] = dp[i-1][other][1] + dp[i-1][other][2]
# 当前位与上一位相同
dp[i][j][2] = dp[i-1][j][1]
total = 0
for j in [0, 1]:
for k in [1, 2]:
total += dp[n][j][k]
return total
动态规划解法的时间复杂度为O(n),空间复杂度可通过滚动数组优化到O(1)。
观察状态转移方程,我们可以发现:
因此可以简化为只记录每个位置以0或1结尾时的总情况数:
python复制def count_stable_binary_optimized(n):
if n == 0: return 0
if n == 1: return 2
# dp0[i]: 长度为i,最后是0
# dp1[i]: 长度为i,最后是1
dp0 = [0]*(n+1)
dp1 = [0]*(n+1)
dp0[1], dp1[1] = 1, 1
for i in range(2, n+1):
dp0[i] = dp1[i-1] + (dp1[i-2] if i > 2 else 0)
dp1[i] = dp0[i-1] + (dp0[i-2] if i > 2 else 0)
return dp0[n] + dp1[n]
进一步观察数列:
| n | count |
|---|---|
| 1 | 2 |
| 2 | 4 |
| 3 | 6 |
| 4 | 10 |
| 5 | 16 |
| 6 | 26 |
可以发现递推关系:f(n) = f(n-1) + f(n-2)
这与斐波那契数列类似,因此可以直接用矩阵快速幂等方法在O(log n)时间内求解。
完整的解决方案需要考虑各种边界情况:
python复制test_cases = [
(0, 0), # 空数组
(1, 2), # [0], [1]
(2, 4), # 所有2位二进制都是稳定的
(3, 6), # 排除000和111
(4, 10),
(5, 16),
]
def test():
for n, expected in test_cases:
assert count_stable_binary(n) == expected
assert count_stable_binary_optimized(n) == expected
print("All tests passed!")
稳定的二进制序列在实际中有多种应用:
扩展问题可以考虑:
对于不同规模的n,算法选择建议:
时间复杂度对比:
在实现过程中容易出现的错误:
调试建议:
关键提示:当n很小时,动态规划的初始化需要特别注意。例如n=2时所有4种组合都有效,这与n≥3时的处理逻辑不同。