一、全排列

  1. var permute = function(nums){
  2. // 1. 设置结果集
  3. const result = [];
  4. // 2. 回溯
  5. const recursion = (path, set) => {
  6. // 2.1 设置回溯终止条件
  7. if (path.length === nums.length) {
  8. // 2.1.1 推入结果集
  9. result.push(path.concat());
  10. // 2.1.2 终止递归
  11. return;
  12. }
  13. // 2.2 遍历数组
  14. for (let i = 0; i < nums.length; i++) {
  15. // 2.2.1 必须是不存在 set 中的坐标
  16. if (!set.has(i)) {
  17. // 2.2.2 本地递归条件(用完记得删除)
  18. path.push(nums[i]);
  19. set.add(i);
  20. // 2.2.3 进一步递归
  21. recursion(path, set);
  22. // 2.2.4 回溯:撤回 2.2.2 的操作
  23. path.pop();
  24. set.delete(i);
  25. }
  26. }
  27. };
  28. recursion([], new Set());
  29. // 3. 返回结果
  30. return result;
  31. };

二、子集

  1. const subsets = (nums) => {
  2. // 1. 设置结果集
  3. const result = [[]];
  4. // 2. 数组排序
  5. nums.sort((a, b) => a - b);
  6. // 3. 递归
  7. const recursion = (index, path) => {
  8. // 3.1 设置终止条件
  9. if (path.length === nums.length) {
  10. return;
  11. }
  12. // 3.2 遍历数组
  13. for (let i = index; i < nums.length; i++) {
  14. // 3.2.1 添加内容
  15. path.push(nums[i]);
  16. // 3.2.2 添加结果集
  17. result.push(path.concat());
  18. // 3.2.3 进一步递归
  19. recursion(i + 1, path);
  20. // 3.2.4 回溯,还原之前状态,以备下一次使用
  21. path.pop();
  22. }
  23. };
  24. recursion(0, []);
  25. // 4. 返回结果
  26. return result;
  27. };

三、组合

  1. var combine = function (n, k) {
  2. const res = []
  3. if (k <= 0 || n <= 0) return res;
  4. const track = [];
  5. const backtrack = (n, k, start, track) => {
  6. // 到达树的底部
  7. if (k === track.length) {
  8. res.push(track.concat());
  9. return;
  10. }
  11. // 注意i从start开始递增
  12. for (let i = start; i <= n; i++) {
  13. // 做选择
  14. track.push(i);
  15. backtrack(n, k, i + 1, track);
  16. // 撤销选择
  17. track.pop();
  18. }
  19. }
  20. backtrack(n, k, 1, track);
  21. return res;
  22. };