编程算法面试题

回溯框架:排列、组合、子集

你的回溯模板长什么样?排列/组合/子集三者区别?

为什么面试官会问这道题

回溯题频繁、面试友好,一个模板能解决大部分。

如何回答

  1. 1

    模板:每个决策点尝试每个合法选择→递归→撤销(pop)。三步曲:"选→递→回"。

  2. 2

    子集:每个元素选或不选,2^n个输出。每个节点都收集path。

  3. 3

    组合:子集+大小为k约束(path.size>k剪枝,或靠start指针限制)。

  4. 4

    排列:顺序有意义。维护used[]或原地交换。n!个输出。

  5. 5

    剪枝:排序后跳重复、剩余不够达标(子集和)就剪、对比已知最优值剪。

参考回答示例

一个模板:`void dfs(path, state){ if(终止){收集path; return;} for(choice in 可选(state)){ 做选择; dfs(path+choice, 下一状态); 撤销; } }`。子集每次递归都收集(无终止门),排列用visited[]跳已选,组合内循环从i+1开始。重复数据我先排序再`if i>start && nums[i]==nums[i-1] 跳`。剪枝决定过不过TLE——子集和里已超就砍、N皇后里用集合存对角线O(1)判断。递归树形状告诉我最坏复杂度:子集2^n、排列n!。

实用技巧

  • 显式撤销比每次复制path易于推理。

  • visited[]比从list里删O(1),从list删O(n)。

  • 即答侠给了子集/排列/组合的单页cheat sheet,附带去重模板。

常见问题

回溯和DFS区别?

回溯就是DFS,多了显式撤销步骤所以能探下一个选择。DFS是更宽的概念。

什么时候可以提前剪枝?

任何单调上界能证明"这支没戏"时。先排序常常能开启剪枝机会。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠