zoukankan      html  css  js  c++  java
  • 40. 组合总和 II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的每个数字在每个组合中只能使用一次。

    说明:

    所有数字(包括目标数)都是正整数。
    解集不能包含重复的组合。 
    示例 1:

    输入: candidates = [10,1,2,7,6,1,5], target = 8,
    所求解集为:
    [
    [1, 7],
    [1, 2, 5],
    [2, 6],
    [1, 1, 6]
    ]
    示例 2:

    输入: candidates = [2,5,2,1,2], target = 5,
    所求解集为:
    [
      [1,2,2],
      [5]
    ]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/combination-sum-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    class Solution:
        def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
            
            size = len(candidates)
            if size == 0:
                return []
            
            candidates.sort()
            
            path = []
            res = []
            self._find_path(candidates, path, res, target, 0, size)
            
            return res
        
        def _find_path(self, candidates, path, res, target, begin, size):
            if target == 0:
                res.append(path.copy())
            else:
                for i in range(begin, size):
                    left_num = target - candidates[i]
                    if left_num < 0:
                        break
    
                    if i > begin and candidates[i] == candidates[i-1]:
                        continue
                    path.append(candidates[i])
    
                    self._find_path(candidates, path, res, left_num, i+1, size)#这里需要i+1
                    path.pop()
    class Solution {
        public List<List<Integer>> combinationSum2(int[] nums, int target) {
            List<List<Integer>> list = new ArrayList<>();
            Arrays.sort(nums);
            backtrack(list, new ArrayList<>(), nums, target, 0);
            return list;
        }
    
        private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
            if(remain < 0) return;
            else if(remain == 0) list.add(new ArrayList<>(tempList));
            else{
                for(int i = start; i < nums.length; i++){
                    if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
                    tempList.add(nums[i]);
                    backtrack(list, tempList, nums, remain - nums[i], i + 1);
                    tempList.remove(tempList.size() - 1); 
                }
            }
        }
    }

    reference 

    https://leetcode.com/problems/combination-sum/discuss/16502/A-general-approach-to-backtracking-questions-in-Java-(Subsets-Permutations-Combination-Sum-Palindrome-Partitioning)

     
  • 相关阅读:
    20210420
    20210419
    2021041601
    20210416
    20210415
    20210414
    20210413
    20210412
    20210409
    20210405
  • 原文地址:https://www.cnblogs.com/xxxsans/p/13843309.html
Copyright © 2011-2022 走看看