• LeetCode39. 组合总和


    题目

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

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

    分析

    此题和 77题组合题目类似,又有区别。同一个数字可以无限制底被选取,意味着搜索的深度可能不确定,但是我们可以限制搜索的深度,即递归的终止条件是当前总和大于target。

    题目又要求解集不存在重复组合,并且一个数可重复选取,那么每次递归时 startIndex就不必为 i 加一,直接为 i 。

    代码

     1 class Solution {
     2 public:
     3     vector<int>path;
     4     vector<vector<int>> res;
     5     void backtracking(const vector<int>& candidates,int target,int sum,int startIndex){
     6         if(sum > target){
     7             return;
     8         }
     9         if(sum == target){
    10             res.push_back(path);
    11             return;
    12         }
    13         for(int i = startIndex;i < candidates.size();i++){
    14             sum += candidates[i];
    15             path.push_back(candidates[i]);
    16             backtracking(candidates,target,sum,i);
    17             sum -= candidates[i];
    18             path.pop_back();
    19         }
    20     } 
    21     vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    22         backtracking(candidates,target,0,0);
    23         return res;
    24     }
    25 };

    再进行剪枝优化

    上面代码可知,我们是在 sum > target 时,结束递归,实际上在上一次递归尾部就可进行预判,也就是不用进入这层递归,即如果知道下层递归 sum > target 那么就没有必要进入下一层递归了。

    如何进行修改呢 ?我们可以增强进入 for 循环的条件,因为只要进入了 for 循环,就会进入下一层递归。对总集合排序之后,如果下一层的sum(就是本层的 sum + candidates[i])已经大于target,就可以结束本轮for循环的遍历

        for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) 

     1 class Solution {
     2 public:
     3     vector<int>path;
     4     vector<vector<int>> res;
     5     void backtracking(const vector<int>& candidates,int target,int sum,int startIndex){
     6         if(sum > target){
     7             return;
     8         }
     9         if(sum == target){
    10             res.push_back(path);
    11             return;
    12         }
    13         for(int i = startIndex;i < candidates.size() && sum + candidates[i] <= target;i++){
    14             sum += candidates[i];
    15             path.push_back(candidates[i]);
    16             backtracking(candidates,target,sum,i);
    17             sum -= candidates[i];
    18             path.pop_back();
    19         }
    20     } 
    21     vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    22         sort(candidates.begin(),candidates.end());
    23         backtracking(candidates,target,0,0);
    24         return res;
    25     }
    26 };

    一定要先进行排序,再去回溯

  • 相关阅读:
    Java字符编码问题
    Andrew Ng机器学习公开课笔记 -- 支持向量机
    Andrew Ng机器学习公开课笔记 -- 朴素贝叶斯算法
    Andrew Ng机器学习公开课笔记 -- Generative Learning algorithms
    Andrew Ng机器学习公开课笔记 -- Generalized Linear Models
    技术书单整理
    Andrew Ng机器学习公开课笔记 -- Logistic Regression
    Andrew Ng机器学习公开课笔记 -- 线性回归和梯度下降
    统计学习方法笔记 -- 决策树
    POJ1037 A decorative fence 【动态规划】
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14341825.html
Copyright © 2020-2023  润新知