zoukankan      html  css  js  c++  java
  • [LeetCode] 40. Combination Sum II 组合之和 II

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

    Each number in candidates 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.

    Example 1:

    Input: candidates = [10,1,2,7,6,1,5], target = 8,
    A solution set is:
    [
      [1, 7],
      [1, 2, 5],
      [2, 6],
      [1, 1, 6]
    ]
    

    Example 2:

    Input: candidates = [2,5,2,1,2], target = 5,
    A solution set is:
    [
      [1,2,2],
      [5]
    ]

    39. Combination Sum 的变形,39题数组中的数字可以重复使用,而这道题数组中的数字不能重复使用。这里要考虑跳过重复的数字,其它的与39题一样。

    解法:和39一样,递归 + backtracking

    Java:

    public List<List<Integer>> combinationSum2(int[] cand, int target) {
        Arrays.sort(cand);
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> path = new ArrayList<Integer>();
        dfs_com(cand, 0, target, path, res);
        return res;
    }
    void dfs_com(int[] cand, int cur, int target, List<Integer> path, List<List<Integer>> res) {
        if (target == 0) {
            res.add(new ArrayList(path));
            return ;
        }
        if (target < 0) return;
        for (int i = cur; i < cand.length; i++){
            if (i > cur && cand[i] == cand[i-1]) continue;
            path.add(path.size(), cand[i]);
            dfs_com(cand, i+1, target - cand[i], path, res);
            path.remove(path.size()-1);
        }
    }  

    Java:

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> curr = new ArrayList<Integer>();
        Arrays.sort(candidates);
        helper(result, curr, 0, target, candidates);
        return result;
    }
     
    public void helper(List<List<Integer>> result, List<Integer> curr, int start, int target, int[] candidates){
        if(target==0){
            result.add(new ArrayList<Integer>(curr));
            return;
        }
        if(target<0){
            return;
        }
     
        int prev=-1;
        for(int i=start; i<candidates.length; i++){
            if(prev!=candidates[i]){ // each time start from different element
                curr.add(candidates[i]);
                helper(result, curr, i+1, target-candidates[i], candidates); // and use next element only
                curr.remove(curr.size()-1);
                prev=candidates[i];
            }
        }
    }  

    Python:

    class Solution:
        # @param candidates, a list of integers
        # @param target, integer
        # @return a list of lists of integers
        def combinationSum2(self, candidates, target):
            result = []
            self.combinationSumRecu(sorted(candidates), result, 0, [], target)
            return result
        
        def combinationSumRecu(self, candidates, result, start, intermediate, target):
            if target == 0:
                result.append(list(intermediate))
            prev = 0
            while start < len(candidates) and candidates[start] <= target:
                if prev != candidates[start]:
                    intermediate.append(candidates[start])
                    self.combinationSumRecu(candidates, result, start + 1, intermediate, target - candidates[start])
                    intermediate.pop()
                    prev = candidates[start]
                start += 1
    

    C++:

    class Solution {
    public:
        vector<vector<int> > combinationSum2(vector<int> &num, int target) {
            vector<vector<int> > res;
            vector<int> out;
            sort(num.begin(), num.end());
            combinationSum2DFS(num, target, 0, out, res);
            return res;
        }
        void combinationSum2DFS(vector<int> &num, int target, int start, vector<int> &out, vector<vector<int> > &res) {
            if (target < 0) return;
            else if (target == 0) res.push_back(out);
            else {
                for (int i = start; i < num.size(); ++i) {
                    if (i > start && num[i] == num[i - 1]) continue;
                    out.push_back(num[i]);
                    combinationSum2DFS(num, target - num[i], i + 1, out, res);
                    out.pop_back();
                }
            }
        }
    };  

    类似题目:

    [LeetCode] 39. Combination Sum 组合之和

  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8674181.html
Copyright © 2011-2022 走看看