回溯
约 10 分钟
回溯是“做选择 → 递归深入 → 撤销选择”的搜索框架:走到某一步做出一个选择,沿着它往下搜;这条路探完后,一定要把选择撤销、恢复现场,再去试下一个选择。关键就在“恢复现场”。
以全排列为例:
int a[10];
bool used[10];
void dfs(int step) {
if (step == n) { /* 输出一个排列 */ return; }
for (int i = 1; i <= n; i++) {
if (used[i]) continue;
used[i] = true; a[step] = i; // 做选择
dfs(step + 1);
used[i] = false; // 撤销选择, 恢复现场
}
}
全排列共 种,复杂度 ,所以 一般很小( 左右)。
坑:一是最容易漏写 used[i] = false 这行撤销,一漏就只能搜出一条路;二是“做选择”和“撤销选择”必须成对出现、前后对称;三是若用了全局的路径数组或计数器,回溯时也要一并还原,否则状态会串到别的分支。
小纸条
写一个全排列。
登录 后可看答案