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

.........

.........

.........

相关推荐
爱睡懒觉的焦糖玛奇朵7 小时前
【从视频到数据集:焦糖玛奇朵的魔法工具使用说明】
人工智能·python·深度学习·学习·算法·yolo·音视频
Runawayliquor7 小时前
opbase:CANN 所有算子的公共地基
大数据·数据库·人工智能·算法
徐安安ye7 小时前
FlashAttention 为什么对序列长度这么“敏感”?
人工智能·算法
黎阳之光9 小时前
黎阳之光:以视频孪生重构智能监盘,为燃机打造新一代智慧电厂大脑
大数据·人工智能·算法·安全·数字孪生
绝知此事9 小时前
【算法突围 02】树形结构与数据库索引:树形结构与数据库索引:从 BST 到 B+ 树的演化与 MySQL 优化
数据库·mysql·算法·面试·b+树
清木!10 小时前
排序算法比较
数据结构·算法·排序算法
吴可可12310 小时前
用Teigha修改并保存CAD文件
数据库·算法·c#
汉克老师11 小时前
GESP6级C++考试语法知识(十七、数据结构(三、认识队列 Queue))
数据结构·c++·队列·gesp6级·gesp六级·数组模拟队列
灰灰勇闯IT11 小时前
ops-reduce:ReduceMax 与 ReduceMean 的并行优化
算法
水木流年追梦11 小时前
大模型入门-Reward 奖励模型训练
开发语言·python·算法·leetcode·正则表达式