193.回溯算法:组合总和(力扣)

代码解决

class Solution {
public:
    vector<int> res; // 当前组合的临时存储
    vector<vector<int>> result; // 存储所有符合条件的组合
    
    // 回溯函数
    void backtrcing(vector<int>& nums, int target, int flag, int index) {
        // 如果当前组合的和超过了目标值,则返回
        if (flag > target) return;
        
        // 如果当前组合的和等于目标值,则将当前组合加入结果集
        if (flag == target) {
            result.push_back(res);
            return;
        }
        
        // 遍历候选数组
        for (int i = index; i < nums.size(); i++) {
            flag += nums[i]; // 将当前元素加入组合和
            res.push_back(nums[i]); // 将当前元素加入当前组合
            backtrcing(nums, target, flag, i); // 递归调用回溯函数,允许重复使用当前元素
            flag -= nums[i]; // 回溯,移除当前元素
            res.pop_back(); // 回溯,移除当前元素
        }
    }
    
    // 主函数
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtrcing(candidates, target, 0, 0); // 初始调用回溯函数
        return result; // 返回所有符合条件的组合
    }
};

测试用例

输入

vector<int> candidates = {2, 3, 6, 7}; int target = 7;

输出

[ [2, 2, 3], [7] ]

过程描述

  1. 初始状态

    • candidates = {2, 3, 6, 7}
    • target = 7
    • res = [](当前组合为空)
    • result = [](所有符合条件的组合为空)
  2. 递归回溯

    • 从第一个元素 2 开始:
      • flag = 2res = [2],继续递归。
      • 再次选择 2
        • flag = 4res = [2, 2],继续递归。
        • 再次选择 2
          • flag = 6res = [2, 2, 2],继续递归。
          • 再次选择 2
            • flag = 8,超过目标值,回溯,移除最后一个 2
        • 尝试选择 3
          • flag = 7res = [2, 2, 3],符合目标值,将组合加入 result,回溯,移除最后一个 3
        • 尝试选择 67
          • 超过目标值,回溯。
      • 尝试选择 3
        • flag = 5res = [2, 3],继续递归。
        • 再次选择 3
          • 超过目标值,回溯。
        • 尝试选择 67
          • 超过目标值,回溯。
    • 尝试选择 3
      • flag = 3res = [3],继续递归。
      • 再次选择 3
        • flag = 6res = [3, 3],继续递归。
        • 尝试选择 367
          • 超过目标值,回溯。
    • 尝试选择 6
      • flag = 6res = [6],继续递归。
      • 尝试选择 67
        • 超过目标值,回溯。
    • 尝试选择 7
      • flag = 7res = [7],符合目标值,将组合加入 result

最终,result 包含所有符合条件的组合 [[2, 2, 3], [7]]

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清酒。233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值