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

.........

.........

.........

相关推荐
lvwangshu22 分钟前
exBSGS 算法
数学·算法
不会就选b23 分钟前
算法日常・每日刷题--<贪心+大根堆>2
数据结构·算法
码艺-Alimjan25 分钟前
维吾尔语数字转文本
java·javascript·python·算法·go
AI服务老曹28 分钟前
算法任务配置完整流程:明厨亮灶项目从0到1怎么做 | AI视频分析算法实践
人工智能·算法·音视频
事圆则缓32 分钟前
Java 常见数据结构与 Android 使用场景
android·java·数据结构
hahaha601638 分钟前
HLS高层次综合设计--axi之burst纠偏
开发语言·算法·fpga开发·c#
hans汉斯43 分钟前
【计算机科学与应用】基于联合熵驱动改进麻雀搜索优化VMD的DAS信号去噪方法
深度学习·算法·yolo·软件工程·汉斯出版社
词却1 小时前
机器学习入门:手写数字识别与算法对比
人工智能·算法·机器学习
张欣-男1 小时前
3分钟理解线性代数
线性代数·算法
白狐_7981 小时前
408 数据结构|外部排序优化:怎么减少时间开销
数据结构·算法