zoukankan      html  css  js  c++  java
  • 39.Combination Sum

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

    题目大意:给出一串数字(没有重复数字)和一个数字,找出所有组合数的和与这个数字相等的组合数,其中组合数的每一个数字可以重复选,例子如下:

    法一:利用78题的法一,只是这里对target有所限制,还要注意可以重复取数字。代码如下(耗时23ms):

     1     public List<List<Integer>> combinationSum(int[] candidates, int target) {
     2         List<List<Integer>> res = new ArrayList<List<Integer>>();
     3         List<Integer> tmp = new ArrayList<Integer>();
     4         dfs(res, tmp, candidates, target, 0);
     5         return res;
     6     }
     7     public static void dfs(List<List<Integer>> res, List<Integer> tmp, int[] candidates, int target, int start) {
     8         if(target == 0) {//递归结束条件
     9             res.add(new ArrayList<Integer>(tmp));
    10             return;
    11         }
    12         else if(target > 0){//这里一定要判断target>0,因为如果不判断就会导致target<0时还在往下递归
    13             for(int i = start; i < candidates.length; i++) {
    14                 tmp.add(candidates[i]);
    15                 dfs(res, tmp, candidates, target - candidates[i], i);//这里不是i+1而是i,因为可以重复选
    16                 tmp.remove(tmp.size() - 1);
    17             }
    18         }
    19     }
    View Code

    剪枝,先排序,然后在递归的时候,一旦总和<=0则跳出后面的循环。代码如下(耗时18ms):

     1     public List<List<Integer>> combinationSum(int[] candidates, int target) {
     2         List<List<Integer>> res = new ArrayList<List<Integer>>();
     3         List<Integer> tmp = new ArrayList<Integer>();
     4         Arrays.sort(candidates);//先进行排序
     5         dfs(res, tmp, candidates, target, 0);
     6         return res;
     7     }
     8     public static boolean dfs(List<List<Integer>> res, List<Integer> tmp, int[] candidates, int target, int start) {
     9         if(target < 0) {
    10             return false;
    11         }
    12         if(target == 0) {//递归结束条件
    13             res.add(new ArrayList<Integer>(tmp));
    14             return false;
    15         }
    16         else {//这里一定要判断target>0,因为如果不判断就会导致target<0时还在往下递归
    17             for(int i = start; i < candidates.length; i++) {
    18                 tmp.add(candidates[i]);
    19                 boolean flag = dfs(res, tmp, candidates, target - candidates[i], i);//这里不是i+1而是i,因为可以重复选
    20                 tmp.remove(tmp.size() - 1);
    21                 //剪枝,因为数组是排好序的,所以一旦总和<=0,那么其后的数字一定会导致当前结果<0,所以可以直接从此跳过后面的循环
    22                 if(flag == false) {
    23                     break;
    24                 }
    25             }
    26         }
    27         return true;
    28     }
    View Code

     另一个方法剪枝,不用等到总和<=0才剪枝,而是在dfs之前就判断是否能选该数,否则就跳出循环。代码如下(耗时15ms):

     1     public List<List<Integer>> combinationSum(int[] candidates, int target) {
     2         List<List<Integer>> res = new ArrayList<List<Integer>>();
     3         List<Integer> tmp = new ArrayList<Integer>();
     4         Arrays.sort(candidates);
     5         dfs(res, tmp, candidates, target, 0);
     6         return res;
     7     }
     8     public static void dfs(List<List<Integer>> res, List<Integer> tmp, int[] candidates, int target, int start) {
     9         if(target == 0) {//递归结束条件
    10             res.add(new ArrayList<Integer>(tmp));
    11             return;
    12         }
    13         else if(target > 0){//这里一定要判断target>0,因为如果不判断就会导致target<0时还在往下递归
    14             for(int i = start; i < candidates.length; i++) {
    15                 //快速剪枝
    16                 if(target < candidates[i]) {
    17                     break;
    18                 }
    19                 tmp.add(candidates[i]);
    20                 dfs(res, tmp, candidates, target - candidates[i], i);//这里不是i+1而是i,因为可以重复选
    21                 tmp.remove(tmp.size() - 1);
    22             }
    23         }
    24     }
    View Code
  • 相关阅读:
    禁用LinkButton的方法
    Windows Server2008R2中导入Excel
    Viewport
    Firefox模拟手机访问手机网站
    关闭ReSharper中的[ Use 'var' ]提示(Disable C# “var” Recommendation in ReSharper)
    浏览器中如何获取想要的offsetwidth、、、clientwidth、、offsetheight、、、clientheight。。。
    JS中关于clientWidth offsetWidth scrollWidth 等的含义的详细介绍
    base64编码解码js
    scrollTop如何实现click后页面过渡滚动到顶部
    如何快速获取当前链接?后面的内容,location.search、页面滚动
  • 原文地址:https://www.cnblogs.com/cing/p/7883257.html
Copyright © 2011-2022 走看看