回溯算法

回溯算法原理与常见题型

#resource / algorithm #type / concept #status / growing #algo / backtracking

[!info] related notes 算法面试题型 MOC DFS / BFS / 回溯

回溯

入门回溯

子集型

子集

每个元素是选还是不选

模板1(输入角度)

  • 当前操作? 枚举第 i 个数选/不选
  • 子问题? 从下标 >= i 的数字中构造子集
  • 下一个子问题? 从下标 >= i+1 的数字中构造子集

var subsets = function(nums) {
    let res = [];
    let path =[];

    function dfs(i) {
        if (i === nums.length) {
            res.push([...path]);
            return;
        }

        dfs(i+1); // 不选,直接跳过当前数,进入下一个数

        path.push(nums[i]);
        dfs(i+1); // 选,添加后进入下一个数
        path.pop();  //恢复现场

    }
    dfs(0);
    return res;
};

模板2(站在答案视角)

  • 当前操作? 枚举 1 个下标 j >= i 的数字加入 path
  • 子问题? 从下标 >= i 的数字中构造子集
  • 下一个子问题? 从下标 >= j+1 的数字中构造子集

每个节点都是答案


var subsets = function (nums) {
    let res = [];
    let path = [];

    function dfs(i) {
        res.push([...path]); // 每个节点都是结果
        if (i === nums.length) {
            return;
        }
        for (let j = i; j < nums.length; j++) {
            path.push(nums[j]);
            dfs(j + 1);
            path.pop();
        }
    }
    dfs(0);
    return res;
};

划分型回溯

把分割线(逗号)看成是可以「选或不选」的东西,本质是子集型回溯。

组合型

排列型

创建于 2025/1/1 更新于 2026/5/27