zoukankan      html  css  js  c++  java
  • Leetcode 之 Combination Sum系列

    39. Combination Sum

    1.Problem

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

    Example 1:

    Input: k = 3, n = 7

    Output:

    [[1,2,4]]
    

    Example 2:

    Input: k = 3, n = 9

    Output:

    [[1,2,6], [1,3,5], [2,3,4]]

    2.Solution

       题目的大意是给定一个元素不存在重复的一维数组candidates和一个目标数target,输出由一位数组中的数可以组成target的所有组合类型,注:candidates中的数可以重复使用的

       对给定的数组进行排序,然后针对target进行回溯。

    3.Code

     1 package test;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Arrays;
     5 import java.util.List;
     6 
     7 public class TaskTest {
     8     private List<List<Integer>> result = new ArrayList<List<Integer>>();
     9     private int[] temp;
    10     public static void main(String[] args) {
    11         int[] a = {2,3,6,7};
    12         
    13         new TaskTest().combinationSum(a,7);
    14         //System.out.println();
    15     }
    16     
    17     public List<List<Integer>> combinationSum(int[] candidates, int target) {
    18         //[2, 3, 6, 7] and target 7
    19         this.temp = candidates;
    20         Arrays.sort(temp);
    21         List<Integer> current = new ArrayList<>();
    22         backTracing(current,0,target);
    23         System.out.println(this.result.toString());
    24         return result;
    25     }
    26     
    27     public void backTracing(List<Integer> current , int index , int target) {
    28         if ( target == 0 ) {
    29             List<Integer> list = new ArrayList<>(current);
    30             result.add(list);
    31         } else {
    32             for ( int i = index ; i < temp.length && temp[i] <= target ; i++ ) {
    33                 current.add(temp[i]);
    34                 backTracing(current,i,target - temp[i]);
    35                 current.remove(new Integer(temp[i]));
    36             }
    37         }
    38     }
    39 }
    View Code

    4.提交Leetcode的代码

     40. Combination Sum II

    1.Problem

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

    Each number in C may only be used once in the combination.

    Note:

    • All numbers (including target) will be positive integers.
    • The solution set must not contain duplicate combinations.

    For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,
    A solution set is:

    [
      [1, 7],
      [1, 2, 5],
      [2, 6],
      [1, 1, 6]
    ]

    2.Soluton

       Combination Sum II跟 I比不同点在于,II中的一维数组中元素允许重复,但是组成target的每个元素仅允许被使用一次

    1. backTracing(current,i + 1 ,target - temp[i]); 位置变为 i + 1
    2. 处理结果中存在的重复问题
    3. 输出的结果跟顺序无关,即([[1,1,6],[1,2,5],[1,7],[2,6]]) 和([[1,2,5],[1,1,6],[2,6],[1,7]])是相同的,都是正确的结果

    3.Code

     1 package test;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Arrays;
     5 import java.util.HashSet;
     6 import java.util.Iterator;
     7 import java.util.List;
     8 import java.util.Set;
     9 
    10 public class TaskTest {
    11     private List<List<Integer>> result = new ArrayList<List<Integer>>();
    12     private int[] temp;
    13     public static void main(String[] args) {
    14         int[] a = {1,1,2,5,6,7,10};
    15         
    16         
    17         new TaskTest().combinationSum(a,8);
    18         //System.out.println();
    19     }
    20     
    21     public List<List<Integer>> combinationSum(int[] candidates, int target) {
    22         //[2, 3, 6, 7] and target 7
    23         this.temp = candidates;
    24         Arrays.sort(temp);
    25         List<Integer> current = new ArrayList<>();
    26         backTracing(current,0,target);
    27         System.out.println(this.result.toString());
    28         Set<List<Integer>> set = new HashSet<>();
    29         for (List<Integer> l : result ) {
    30             if ( !set.contains(l)) {
    31                 set.add(l);
    32             }
    33         }
    34         System.out.println(set.toString());
    35         result.clear();
    36         Iterator<List<Integer>> i = set.iterator();
    37         while ( i.hasNext() ) {
    38           result.add(i.next());    
    39         }
    40         System.out.println(result.toString());
    41         return result;
    42     }
    43     
    44     public void backTracing(List<Integer> current , int index , int target) {
    45         if ( target == 0 ) {
    46             List<Integer> list = new ArrayList<>(current);
    47             result.add(list);
    48         } else {
    49             for ( int i = index ; i < temp.length && temp[i] <= target ; i++ ) {
    50                 current.add(temp[i]);
    51                 backTracing(current,i + 1 ,target - temp[i]);
    52                 current.remove(new Integer(temp[i]));
    53             }
    54         }
    55     }
    56 }
    View Code

    4.提交Leetcode的代码

      

    216. Combination Sum III

    1.Problem

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

     

    Example 1:

    Input: k = 3, n = 7

    Output:

    [[1,2,4]]
    

     

    Example 2:

    Input: k = 3, n = 9

    Output:

    [[1,2,6], [1,3,5], [2,3,4]]

    2.Solution

       一维数组固定为{1,2,3,4,5,6,7,8,9},要求了组成target的数的个数,同样要求数字不能重复使用

    3.Code

    package test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Set;
    
    public class TaskTest {
        private List<List<Integer>> result = new ArrayList<List<Integer>>();
        private int[] temp = {1,2,3,4,5,6,7,8,9};
        public static void main(String[] args) {
            new TaskTest().combinationSum(3,9);
            //System.out.println();
        }
        
        public List<List<Integer>> combinationSum(int k, int target) {
            //[2, 3, 6, 7] and target 7
            List<Integer> current = new ArrayList<>();
            backTracing(current,0,target);
            for ( int i = 0 ; i < result.size() ; i++ ) {
                List<Integer> l = result.get(i);
                
                if (l.size() != k ) {
                    System.out.println(l.toString());
                    result.remove(i);
                    i--;
                }
            }
            System.out.println(result.toString());
            return result;
        }
        
        public void backTracing(List<Integer> current , int index , int target) {
            if ( target == 0 ) {
                List<Integer> list = new ArrayList<>(current);
                result.add(list);
            } else {
                for ( int i = index ; i < temp.length && temp[i] <= target ; i++ ) {
                    current.add(temp[i]);
                    backTracing(current,i + 1 ,target - temp[i]);
                    current.remove(new Integer(temp[i]));
                }
            }
        }
    }
    View Code

    4.提交Leetcode的代码

    377. Combination Sum IV

    1.Problem

    Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.

    Example:

    nums = [1, 2, 3]
    target = 4
    
    The possible combination ways are:
    (1, 1, 1, 1)
    (1, 1, 2)
    (1, 2, 1)
    (1, 3)
    (2, 1, 1)
    (2, 2)
    (3, 1)
    
    Note that different sequences are counted as different combinations.
    
    Therefore the output is 7.
    

    2.Solution

       动态规划,转移方程为:dp[n] = dp[n] + dp[n-nums[k]] (dp[0] = 1, 即n - nums[k] == 0时 ),dp[i] 代表给定的数组能组成i的种类数

    3.Code

    class Solution {
        public int combinationSum4(int[] nums, int target) {
            int[] dp = new int[target + 1];
            dp[0] = 1;
            Arrays.sort(nums);
            DP(target , nums , dp);
            return dp[target];
        }

        public void DP ( int target , int[] nums , int[] dp ) {
           for ( int i = 1 ; i <= target ; i++ ) {
                for ( int j = 0 ; j < nums.length ; j++ ) {
                    if ( i - nums[j] >= 0 ) {
                        dp[i] = dp[i] + dp[ i - nums[j] ];
                    } else {
                        break;
                    }
                }
           }
        }
    }

    //预先对nums进行排序然后循环中加break,leetcode 提交从18.02%提升到65.16%

    4.提交Leetcode的代码



  • 相关阅读:
    「2020 新手必备 」极速入门 Retrofit + OkHttp 网络框架到实战,这一篇就够了!
    结合源码,重温 Android View 的事件处理知多少 ?
    Android 这 13 道 ContentProvider 面试题,你都会了吗?
    17 个必须掌握的 BroadcastReceiver 知识点「建议收藏」
    23 个重难点突破,带你吃透 Service 知识点「长达 1W+ 字」
    Activity 的 36 大难点,你会几个?「建议收藏」
    Python time模块
    vue项目的创建
    githunb和码云生成/添加SSH公钥
    weex打包apk步骤
  • 原文地址:https://www.cnblogs.com/fangpengchengbupter/p/7338121.html
Copyright © 2011-2022 走看看