leetcode回溯算法(39.组合总和)

cpp 复制代码
class Solution {
private:
    vector<vector<int>> result; // 存储所有符合条件的组合
    vector<int> path; // 当前搜索路径(当前组合)
    
    // 回溯函数
    // candidates: 候选数字数组
    // target: 目标总和
    // sum: 当前路径中数字的总和
    // startIndex: 当前搜索开始位置(防止重复组合)
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
        // 终止条件1:当前和已经超过目标值
        if (sum > target) {
            return; // 直接返回,不再继续搜索
        }
        
        // 终止条件2:当前和等于目标值
        if (sum == target) {
            result.push_back(path); // 找到有效组合,加入结果集
            return; // 返回上一层
        }

        // 从startIndex开始遍历候选数字
        for (int i = startIndex; i < candidates.size(); i++) {
            sum += candidates[i]; // 选择当前数字,更新总和
            path.push_back(candidates[i]); // 将当前数字加入路径
            
            // 递归调用,注意这里传的是 i 而不是 i+1
            // 因为允许重复使用同一个数字
            backtracking(candidates, target, sum, i);
            
            // 回溯:撤销选择
            sum -= candidates[i]; // 从总和中减去当前数字
            path.pop_back(); // 从路径中移除当前数字
        }
    }
    
public:
    // 主函数:组合总和
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear(); // 清空结果集
        path.clear(); // 清空当前路径
        // 从第0个位置开始回溯搜索
        backtracking(candidates, target, 0, 0);
        return result; // 返回所有符合条件的组合
    }
};

例子candidates = [2,3,6,7], target = 7

初始状态:

复制代码
result = []
path = []
sum = 0
startIndex = 0

第一层递归:backtracking([2,3,6,7], 7, 0, 0)

cpp 复制代码
for (int i = startIndex; i < candidates.size(); i++) {
        sum += candidates[i];
        path.push_back(candidates[i]);
        backtracking(candidates, target, sum, i); // 不用i+1了,表示可以重复读取当前的数
复制代码
不满足前面if条件
for循环,开始 i=0
sum = sum + candidates[0] = 0 + 2 = 2
path = [2]
进入递归...backtrackint([2,3,6,7], 7, 2, 0)

第二层递归:backtracking([2,3,6,7], 7, 2, 0)

复制代码
不满足前面if条件
for循环,开始 i=0
sum = sum + candidates[0] = 2 + 2 = 4
path = [2,2]
进入递归...backtracking([2,3,6,7], 7, 4, 0)

第三层递归:backtracking([2,3,6,7], 7, 4, 0)

复制代码
for循环,开始 i=0
sum = sum + candidates[0] = 4 + 2 = 6
path = [2,2,2]
进入递归...backtracking([2,3,6,7], 7, 6, 0)

第四层递归:backtracking([2,3,6,7], 7, 6, 0)

复制代码
for循环,开始 i=0
cpp 复制代码
       for (int i = startIndex; i < candidates.size(); i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum, i); // 不用i+1了,表示可以重复读取当前的数
复制代码
// 选择 candidates[0] = 2
sum += candidates[i];    // sum = 6 + 2 = 8
path.push_back(candidates[i]);  // path = [2,2,2,2]
backtracking(candidates, target, sum, i);
// 参数:candidates=[2,3,6,7], target=7, sum=8, i=0

进入第五层递归(由于 sum=8 > target=7

复制代码
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
    if (sum > target) {  // 8 > 7? true
        return;  // 立即返回
    }
    // ... 不会执行后续代码
}

回溯(撤销选择)

复制代码
// 返回到第四层递归,继续执行
sum -= candidates[i];    // sum = 8 - 2 = 6
path.pop_back();         // path = [2,2,2]
// 循环继续...
复制代码
for循环,开始 i=1
cpp 复制代码
       for (int i = startIndex; i < candidates.size(); i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum, i); // 不用i+1了,表示可以重复读取当前的数
复制代码
// 选择 candidates[1] = 3
sum += candidates[i];    // sum = 6 + 3 = 9
path.push_back(candidates[i]);  // path = [2,2,2,3]
backtracking(candidates, target, sum, i);
// 参数:candidates=[2,3,6,7], target=7, sum=9, i=0

.........

.........

.........

相关推荐
孤狼warrior9 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Σίσυφος190010 小时前
PCL法向量估计 之 RANSAC 平面估计法向量
算法·机器学习·平面
xhbaitxl10 小时前
算法学习day39-动态规划
学习·算法·动态规划
I_LPL10 小时前
day23 代码随想录算法训练营 回溯专题2
算法·hot100·回溯算法·求职面试
智者知已应修善业10 小时前
【洛谷P9975奶牛被病毒传染最少数量推导,导出多样例】2025-2-26
c语言·c++·经验分享·笔记·算法·推荐算法
m0_7369191010 小时前
C++中的委托构造函数
开发语言·c++·算法
小小小小王王王10 小时前
洛谷-P1886 【模板】单调队列 / 滑动窗口
c++·算法
PPPPPaPeR.11 小时前
光学算法实战:深度解析镜片厚度对前后表面折射/反射的影响(纯Python实现)
开发语言·python·数码相机·算法
看我干嘛!11 小时前
python第五次作业
算法
历程里程碑11 小时前
Linux 库
java·linux·运维·服务器·数据结构·c++·算法