zoukankan      html  css  js  c++  java
  • 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 };

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

  • 相关阅读:
    blender 2.8 [学习笔记-033] 编辑模式-滑动边线
    blender 2.8 [学习笔记-032] 编辑模式-随机(光滑)
    blender 2.8 [学习笔记-031] 编辑模式-光滑
    blender 2.8 [学习笔记-030] 编辑模式-旋转
    blender 2.8 [学习笔记-029] 编辑模式-多边形建形
    TurtleBot3使用课程-第一节a(北京智能佳)
    ViperX 300 Robot Arm 机械臂 “5自由度和360°全方位旋转”
    TurtleBot 3 & 2i ROS开源实验平台
    在人工智能实验平台下对主流舵机的简介
    走进车联网,你将更深入地了解无人车和自动驾驶技术
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14341825.html
Copyright © 2011-2022 走看看