2021-09-11 刷题 39. 组合总和

题目链接:https://leetcode-cn.com/problems/combination-sum/

题目说明:

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

candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。

对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
示例 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]]
示例 3:

输入: candidates = [2], target = 1
输出: []
示例 4:

输入: candidates = [1], target = 1
输出: [[1]]
示例 5:

输入: candidates = [1], target = 2
输出: [[1,1]]

题目思想:

本题会涉及到一个新的算法思想:回溯算法

1、本题属于组合总和的问题,特点是,组合不排序;可以使用回溯法,也是一种树形结构

2、回溯法的三部曲 1) 确定函数的参数以及返回值类型

         2)确定终止条件<递归>

         3)确定单层的搜索逻辑

3、此题的函数已经给出,返回值为整型集合,参数为输入的candidates 集合和目标值target

    终止条件为sum 总和 = target 则返回集合;sum 总和若 > target 则直接return()

 单层的搜索逻辑,为for 循环进行判定集合数值

题目代码:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
            //思想 :用target 与 candidates数组元素进行一对一相减,若减值等于0,则进行输出该数组元素
            //若一对一遍历结束,则进行一对2 
        //定义一组全局变量,二维数组,存放结果集
       vector<vector<int>> ret;
       //定义一组全局变量,存放单一树形结果集
        vector<int> now;
        //初始化sum的总和为0;并且获取candidates的集合长度
        int sum = 0, n = candidates.size();
        function<void(int)> dfs = [&] (int back) {
            if (sum == target) {
                ret.emplace_back(begin(now), end(now));
            } else if (sum > target) return;
            else {
                for (int i = back; i != n; ++i) {
                    now.push_back(candidates[i]);
                    sum += candidates[i];
                    dfs(i);
                    sum -= candidates[i];
                    now.pop_back();
                }
            }
        };
        dfs(0);
        return ret;
    }      
    
};

TIps;push_back 与 emplace_back 的区别

1、两者函数都是将数值进行插入到容器末尾,区别是push_back  是先创建元素,再将元素进行拷贝或者移除到容器;而emplace_back 是直接在容器的末尾创建元素。相比之下,节省了移除或者拷贝元素的时间。

原文地址:https://www.cnblogs.com/gjianli/p/15256701.html