zoukankan      html  css  js  c++  java
  • Combination Sum 解答

    Question

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

    The same repeated number may be chosen from C unlimited number of times.

    Note:

    • All numbers (including target) will be positive integers.
    • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
    • The solution set must not contain duplicate combinations.

    For example, given candidate set 2,3,6,7 and target 7
    A solution set is: 
    [7] 
    [2, 2, 3] 

    Solution 1 -- BFS

    We can also draw the solution tree. For example, input is [2,3,6,7] and 22

                     []

             /     /        

            [2]    [3]    [6]    [7]

          / /       /          

         [2] [3] [6][7]  [3][6][7]  [6][7]  [7]

        .............................................................

    We can find silimar regulation as Problem Subsets

    Difference is here when we find that current sum of list is greater than target number, we will not add it to next array.

     1 public class Solution {
     2     public List<List<Integer>> combinationSum(int[] candidates, int target) {
     3         Arrays.sort(candidates);
     4         List<List<Integer>> result = new ArrayList<List<Integer>>();
     5         List<List<Integer>> current = new ArrayList<List<Integer>>();
     6         Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     7         int length = candidates.length;
     8         for (int i = 0; i < length; i++) {
     9             List<Integer> list = new ArrayList<Integer>();
    10             list.add(candidates[i]);
    11             if (target == candidates[i])
    12                 result.add(list);
    13             if (target > candidates[i])
    14                 current.add(list);
    15             map.put(candidates[i], i);
    16         }
    17         
    18         while (current.size() > 0) {
    19             List<List<Integer>> next = new ArrayList<List<Integer>>();
    20             int l = current.size();
    21             for (int i = 0; i < l; i++) {
    22                 List<Integer> tmp = current.get(i);
    23                 int ll = tmp.size();
    24                 int last = tmp.get(ll - 1);
    25                 int index = map.get(last);
    26                 // Sum up current list
    27                 int total = 0;
    28                 for (int j = 0; j < ll; j++)
    29                     total += tmp.get(j);
    30                 for (int j = index; j < length; j++) {
    31                     if (total + candidates[j] < target) {
    32                         List<Integer> newList = new ArrayList<Integer>(tmp);
    33                         newList.add(candidates[j]);
    34                         next.add(newList);
    35                     } else if (total + candidates[j] == target) {
    36                         List<Integer> newList = new ArrayList<Integer>(tmp);
    37                         newList.add(candidates[j]);
    38                         result.add(newList);
    39                     }
    40                 }
    41             }
    42             current = next;
    43         }
    44         return result;
    45     }
    46 }

    Solution 2 -- DFS

    This also can be solved by DFS. End criterion is leftTarget <= 0.

    Refer to this blog, we have two ways to check duplicated solutions.

    1.       if(i>0 && candidates[i] == candidates[i-1])//deal with dupicate
                     continue; 

     2.       if(!res.contains(item)) 
                    res.add(new ArrayList<Integer>(item));   

     1 public class Solution {
     2     public List<List<Integer>> combinationSum(int[] candidates, int target) {
     3         Arrays.sort(candidates);
     4         List<List<Integer>> result = new ArrayList<List<Integer>>();
     5         for (int i = 0; i < candidates.length; i++) {
     6             dfs(candidates, target, i, result, new ArrayList<Integer>());
     7         }
     8         return result;
     9     }
    10     
    11     private void dfs(int[] nums, int target, int start, List<List<Integer>> result, List<Integer> list) {
    12         if (target < 0)
    13             return;
    14         if (target == 0) {
    15             // Avoid duplicated solutions
    16             if (!result.contains(list))
    17                 result.add(new ArrayList<Integer>(list));
    18             return;
    19         }
    20         for (int i = start; i < nums.length; i++) {
    21             list.add(nums[i]);
    22             dfs(nums, target - nums[i], i, result, list);
    23             list.remove(list.size() - 1);
    24         }
    25     }
    26 }
  • 相关阅读:
    [LUOGU]P1443 马的遍历
    NOIP 2017 D2T1 奶酪
    [0] Hello World
    网络测速 风行天下
    zabbix自动发现与监控内存和CPU使用率最高的进程,监测路由器 风行天下
    网络性能测试工具iperf 风行天下
    Centos7下杀毒软件clamav的安装和使用 风行天下
    LINUX漏洞安全防护防火墙相关 风行天下
    smokeping配置方法 风行天下
    vb+MAPX 数据绑定
  • 原文地址:https://www.cnblogs.com/ireneyanglan/p/4877173.html
Copyright © 2011-2022 走看看