打印最长公共子序列(LCS)结果不全仅输出部分字符如何修复
问题根因
你的回溯打印逻辑分支判断和DP表的填充规则不匹配:当上下两个方向的LCS长度值相等时,你固定选择左移y指针的逻辑,会让回溯路径偏离实际的公共字符位置,直接跳过中间的'c'和'f',最终只输出"ae"。
修复方法
如果你的长度计算逻辑运行正常,memo数组为(a.length()+1) × (b.length()+1)规格,memo[i][j]存储a前i个字符、b前j个字符的LCS长度(常规自底向上DP实现),只需要两处调整即可:
- 把分支判断的大于号改成大于等于,保证值相等时的跳转方向和DP计算时取最大值的逻辑对齐
- 建议用
StringBuilder做拼接后反转,避免每次字符串前置拷贝的性能问题,也规避char类型隐式转换的风险
修复后的核心打印代码:
// 打印LCS代码 int x = a.length(); int y = b.length(); StringBuilder sb = new StringBuilder(); while (x > 0 && y > 0) { if (a.charAt(x - 1) == b.charAt(y - 1)) { sb.append(a.charAt(x - 1)); x--; y--; } else { // 值相等时优先上移x指针,和DP的max取值逻辑对齐 if (memo[x - 1][y] >= memo[x][y - 1]) { x--; } else { y--; } } } // 从后往前收集的字符需要反转得到正序结果 String lcs = sb.reverse().toString(); System.out.println(lcs);
如果你用的是自顶向下的记忆化递归实现,
memo[i][j]存储的是a从i到末尾、b从j到末尾的子串LCS长度,只需要把回溯起点改为x=0, y=0,调整遍历方向为从前往后匹配索引定义即可。
修复后回溯路径会严格沿着DP最大值方向移动,不会遗漏公共字符,对应测试用例会正常输出预期结果"acef"。
内容的提问来源于stack exchange,提问作者Save Soil
相关产品推荐
相关产品推荐

