当C++遇上LeetCode——递归求组合

版权声明:欢迎指出错误,作者极懒,常常懒得修改 https://blog.csdn.net/KevinAshen/article/details/89448718

题目引入

题目:39. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

我的题解

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        combinationSumDFS(candidates, target, 0, {}, res);
        return res;
    }
    void combinationSumDFS(vector<int>& candidates, int target, int start, vector<int> out, vector<vector<int>>& res) {
        if (target < 0) return;
        if (target == 0) {res.push_back(out); return;}
        for (int i = start; i < candidates.size(); ++i) {
            out.push_back(candidates[i]);
            combinationSumDFS(candidates, target - candidates[i], i, out, res);
            out.pop_back();
        }
    }
};

分析

如何想到递归

  • 这道题明显和之前只要计算两数之和之类的题目不一样,我们要的得到的数字之和个数不限,对于这样的题目比较容易想到的就是递归
  • 我们有一个目标target,在选择一个数后,会得到target - 选择数这样一个新的target,继续累加直到获得最后结果

递归函数分析

参数

  • 递归函数(vector& candidates, int target, int start, vector out, vector<vector>& res)这五个参数
    • vector& candidates:输入的数组
    • target:目标数,在前一个数被选择出来后更新
    • start:遍历时的开始下标
    • out:一次结果数组
    • res:最后输出的结果

出入口分析

  • 出口:
    • target < 0, 此时显然已经无法达成target,结束
    • target = 0, 此时target已经达成,可以返回一个正确的out
  • 入口
    • 对于没有满足target的数,从start开始遍历(这里注意一点:start不是i + 1而是i,因为这道题允许重复使用元素,我们只要改变target)
    • 遍历到的数先直接加入out,接着直接开始递归,结束后退出

类似题目

后记

  • 类似题目中这道关键点是要学会去重,可以理解为,我们选择了一个数之后,在递归过程中,这个位置不希望出现一样的数,所以遍历时霸宠的的去掉

猜你喜欢

转载自blog.csdn.net/KevinAshen/article/details/89448718
今日推荐