回溯算法面试题总结:组合、排列、子集、剪枝与 Java 模板
回溯是深度优先搜索的一种写法:把候选方案看成一棵决策树,每层做一次选择,发现不可行就撤销,回到上一个分叉。组合关心选哪些,排列还关心顺序,子集则常在每个节点都收集答案。
统一步骤是:判断终止并记录快照;枚举当前层候选;跳过不合法选择;加入路径;递归下一层;撤销路径。伪代码如下:
1 | search(state): |
去重必须分清层级。同一树层避免选相同值,可在排序后跳过相邻重复候选;同一路径避免重复使用元素,则用 used 数组。剪枝来自约束:剩余元素不足、当前和已超目标、当前方案不会优于最优解时,应提前返回。排序往往让这些判断更早生效。
若每个元素都有选或不选两种可能,搜索规模约 O(2^n);全排列可达 O(n!),保存每个答案还要乘路径复制成本。递归栈通常为 O(n),输出空间另算。回溯并不会消除指数爆炸,只是系统枚举并尽早排除无效分支。
常见误区是忘记撤销、保存了可变路径引用、把“去重”错误地跨层使用,以及在没有单调条件时随意剪枝。小结:先画出决策树,明确每层含义和路径约束,再写选择—递归—撤销,代码自然会稳定。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

