最长稳定子序列(LSS):备忘录表解恢复问题求助
最长稳定子序列(LSS)DP解恢复问题排查指引
问题背景
实现最长稳定子序列的动态规划解法时,已完成computeLSS函数的备忘录表填充逻辑,但从备忘录表恢复具体子序列的环节出错,导致两个测试用例验证失败。
失败测试用例
- 测试用例a2:
[1, 2, 3, 4, 0, 1, -1, -2, -3, -4, 5, -5, -6],预期解长度为8 - 测试用例a3:
[0,2, 4, 6, 8, 10, 12],预期解长度为1
附实现代码
def computeLSS(a): T = {} # Initialize the memo table to empty dictionary # Now populate the entries for the base case n = len(a) for j in range(-1, n): T[(n, j)] = 0 # i = n and j # Now fill out the table : figure out the two nested for loops # It is important to also figure out the order in which you iterate the indices i and j # Use the recurrence structure itself as a guide: see for instance that T[(i,j)] will depend on T[(i+1, j)] # your code here for i in range(0, n + 1): for j in range(-1, n + 1): T[(i, j)] = 0 for i in range(n - 1, -1, -1): for j in range(n - 1 , -1, -1): aj = a[j] if 0 <= j < len(a) else None if aj != None and abs(a[i] - aj) > 1: T[(i, j)] = T[(i + 1, j)] if aj == None or abs(a[i] - aj) <= 1: T[(i, j)] = max(1 + T[(i + 1), i], T[(i + 1, j)]) for i in range(n-2, -1, -1): T[(i, -1)] = max(T[(i+1, -1)], T[(i+1, 0)], T[(i, 0)], 0) i = 0 j = -1 sol = [] while i < n and j < n: if abs(T[(i, j)] - T[(i+1, j)]) > 1: sol.append(a[i]) j = i i = i + 1 return sol
排查与修复指引
1. 先确认备忘录表(T)的正确性
恢复解的前提是DP表计算正确,先排查填充逻辑:
- 重复初始化问题:后续的
for i in 0..n+1循环将所有T[(i,j)]设为0,直接覆盖了最初设置的base case(虽结果一致,但属于冗余操作)。 - j=-1的处理缺失:内层循环j仅遍历
n-1到0,未覆盖j=-1,导致这部分DP值未按递推式计算,后续单独补的T[(i,-1)]逻辑不符合递推规则,完全错误。 - 条件判断冲突:两个
if未做互斥处理(应改用elif),虽当前场景下不会触发覆盖,但逻辑不严谨,存在潜在风险。
2. 恢复解的核心逻辑错误
当前恢复逻辑的判断条件abs(T[(i,j)] - T[(i+1,j)])>1完全不符合DP递推逻辑:
- 递推规则明确:选择
a[i]时,T[(i,j)] = 1 + T[(i+1,i)];不选择时,T[(i,j)] = T[(i+1,j)]。 - 正确判断条件应为:如果
T[(i,j)] == 1 + T[(i+1, i)],说明当前选择了a[i],需将其加入解列表,并更新j=i;否则直接递增i。 - 原条件的错误在于:选择元素时
T[(i,j)]仅比T[(i+1,j)]大1,不会触发abs差>1的判断,导致本该加入的元素被遗漏;而差大于1的情况在正确DP表中几乎不会出现。
针对测试用例a3的具体问题
a3中所有元素两两差值为2,满足abs(a[i]-aj)>1,因此最长稳定子序列只能是单个元素。但由于DP表中j=-1的计算错误,加上恢复逻辑判断失误,导致代码无法正确选择单个元素。
修复步骤
- 修正DP表填充逻辑:
- 移除重复的初始化循环,保留base case
T[(n,j)]=0(j从-1到n-1)。 - 内层循环j覆盖
-1到n-1,确保j=-1的情况按递推式计算。 - 将两个
if改为if-elif,避免逻辑冲突。
- 移除重复的初始化循环,保留base case
- 修正恢复解逻辑:
- 替换判断条件为
T[(i,j)] == 1 + T[(i+1, i)],匹配递推规则。
- 替换判断条件为
内容的提问来源于stack exchange,提问作者stack underflow
相关产品推荐
相关产品推荐

