回溯模板
下面可以看到一个回溯模板,主要的处理还是剪枝
剪纸的部分就来源于这个 for 循环的开始还有 backtrack 的入参
- 如果 for 循环为 0 那么就是每次都会遍历所有的元素,等于没有剪枝
- 如果 for 循环为 start, 这个就牵扯到 backtrack的开始了
- 如果backtrack的开始为 0,那么 for 循环的 开始 也为 0,就是不剪枝
- 如果backtrack的开始为 i,那么 for 循环的 开始 也是当前的元素,就排除了之前遍历的元素
- 如果backtrack的开始为 i + 1,那么 for 循环的 开始 是下一元素,就排除了 0-i的所有元素
var backtrack = function (start, target) {
if (...) {
// 处理满足条件的情况,然后return
return
}
// i 的起始点, 0 还是 start
for (let i = start; i < length; ++i) {
target.push(i)
// 进行回溯的起始点
// 是 0 还是 i 还是 i + 1
backtrack(i + 1, target)
target.pop(i)
}
};
题目
全排列
这两题的区别之处就是一个去重,46题中的集合不包含重复数字,47题包含重复数字
leetcode-46.全排列
leetcode-47. 全排列 II
leetcode-39. 组合总和 (可以重复使用元素)
leetcode-40. 组合总和 II (不可重复使用元素)
leetcode-216.组合总和 III (1-9中选出k个数字之和等于n)
leetcode-# 77. 组合 (1-n
中选k个数字的所有组合)
78 90 这两题一样,只不过90题存在重复元素,需要去重
leetcode-78. 子集
leetcode-90. 子集 II