zoukankan      html  css  js  c++  java
  • [LeetCode#40]Combination Sum II

    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.
    • 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 10,1,2,7,6,1,5 and target 8
    A solution set is: 
    [1, 7] 
    [1, 2, 5] 
    [2, 6] 
    [1, 1, 6]

    Analysis:

    A wrong solution:
    -----------------
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> ret = new ArrayList<List<Integer>> ();
            if (candidates == null || candidates.length == 0 || target == 0)
                return ret;
            ArrayList<Integer> item = new ArrayList<Integer> ();
            Arrays.sort(candidates);
            for (int i = 0; i < candidates.length; i++) 
                helper(candidates, i, ret, item, target, 0);
            return ret;
        }
        
        
        public void helper(int[] candidates, int index, List<List<Integer>> ret, ArrayList<Integer> item, int target, int cur_total)     {
            if (candidates[index] + cur_total >= target) {
                return;
            } else if (candidates[index] + cur_total == target) {
                ArrayList<Integer> temp = new ArrayList<Integer> (item);
                temp.add(candidates[index]);
                ret.add(temp);
            } else {
                item.add(candidates[index]);
                for (int i = index + 1; i < candidates.length; i++)
                    helper(candidates, index + 1, ret, item, target, cur_total + candidates[index]);
                item.remove(item.size() - 1);
            }
        }   
        
    This solution does not take the constraint, that no duplicate combination is allowed in the result set, into consideration. 
    helper(candidates, index + 1, ret, item, target, cur_total + candidates[index]);
    
    As the same design issue in N-Queens 2, we should not try to pass the specific search direction during the recurive, that would incure a lot of child call. We should try to test each possible placement at its step. 
    We should change 
    form a: helper(candidates, index + 1, ret, item, target, cur_total + candidates[index]);
    meaning: The next placement is candidate[index+1].
    --------------------------------------------------------------------------------
    item.add(candidates[index]);
    for (int i = index + 1; i < candidates.length; i++)
        helper(candidates, index + 1, ret, item, target, cur_total + candidates[index]);
    item.remove(item.size() - 1);
    
    into 
    
    form b: helper(candidates, index + 1, target-candidates[i], item, ret);
    meaning: We should start try to place(add) next placement from candidates[index + 1] to candidates[length()-1].  
    --------------------------------------------------------------------------------
    for(int i=start;i<num.length;i++) {
        if(i>start && num[i]==num[i-1]) continue;
        item.add(num[i]);
        helper(num,i+1,target-num[i],item,res);
        tem.remove(item.size()-1);
    }
    
    Note in the form a, we have no idea weather the current placement is a duplicate or not!!!
    Case : candidate: 1, 1, 1, 1, 2  target: 4
    112
    112 (1 result in duplicate)
    1112 (no 1 is not a duplicate)
    When you try to place 1 into the item, you have no idea it would result in duplicate or not.
    Idea: If we could avoid the same element to be repetively placed at the same position of the reuslt string, we can avoid duplicate. 
    1, 1, 1, 2 (each 1 is placed at individual position)
    1, 1, 1(1), 2 (for position 2, we have already placed 1 at this position, we should never try to place 1 at this position again, otherwise, the duplicate case would happen)
    
    In the form b, we could easily detect this situation. Casue at current search, we try to place each candiate into a specific position(item.size()). 
    
    for (int i = start; i < candidates.length; i++) {
                if (i > start && candidates[i] == candidates[i-1]) continue;
                item.add(candidates[i]);
                helper(i+1, candidates, target-candidates[i], item, ret);
                item.remove(item.size()-1);
    }
    if(i>start && num[i]==num[i-1]) continue; Note the checkign i > start. try to differentiate the situation of 1, 1 with 1(1) This checking perfectly avoid the same value was placed at the same position again. It's so elegant and perfect.

    Solution:

    public class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> ret = new ArrayList<List<Integer>> ();
            if (candidates == null || candidates.length == 0 || target <= 0)
                return ret;
            Arrays.sort(candidates);
            ArrayList<Integer> item = new ArrayList<Integer> ();
            helper(0, candidates, target, item, ret);
            return ret;
        }
        
        public void helper(int start, int[] candidates, int target, ArrayList<Integer> item, List<List<Integer>> ret) {
            if (target == 0) {
                ret.add(new ArrayList<Integer> (item));
                return;
            }
            if (target < 0 || start >= candidates.length)
                return;
            for (int i = start; i < candidates.length; i++) {
                if (i > start && candidates[i] == candidates[i-1]) continue;
                item.add(candidates[i]);
                helper(i+1, candidates, target-candidates[i], item, ret);
                item.remove(item.size()-1);
            }
        }
    }
  • 相关阅读:
    Task10 文本预处理
    Task09 批量归一化
    Task06 Basic of CNN
    Task05 梯度消失和梯度爆炸
    Task 04 过拟合,欠拟合及其解决方案
    机器学习 Task 03 多层感知机
    机器学习 task2 softmax与分类模型
    异步与闭包与fetch
    baidu API
    my own JSON
  • 原文地址:https://www.cnblogs.com/airwindow/p/4749329.html
Copyright © 2011-2022 走看看