组合总和问题
1.组合总和1
回溯
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ]
1 class Solution { 2 public List<List<Integer>> combinationSum(int[] candidates, int target) { 3 Arrays.sort(candidates); 4 List<List<Integer>> res = new ArrayList<>(); 5 Stack<Integer> stack = new Stack<>(); 6 helper(candidates,0,target,stack,res); 7 return res; 8 9 } 10 public void helper(int[] candidates,int start,int target,Stack<Integer> stack,List<List<Integer>> res){ 11 if(candidates==null||candidates.length<=0) return; 12 if(target==0){ 13 res.add(new ArrayList<>(stack)); 14 } 15 for(int i=start;i<candidates.length;i++){ 16 if(candidates[i]<=target){ 17 stack.push(candidates[i]); 18 helper(candidates,i,target-candidates[i],stack,res); 19 stack.pop(); 20 } 21 } 22 } 23 }
2.组合总和2
回溯法
给定一个数组 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] ]
1 class Solution { 2 public List<List<Integer>> combinationSum2(int[] candidates, int target) { 3 Arrays.sort(candidates); 4 Stack<Integer> stack = new Stack<>(); 5 List<List<Integer>> res = new ArrayList<>(); 6 helper(candidates,0,target,stack,res); 7 return res; 8 9 } 10 public void helper(int[] candidates,int start,int target,Stack<Integer> stack,List<List<Integer>> res){ 11 if(target==0){ 12 res.add(new ArrayList<>(stack)); 13 return; 14 } 15 for(int i=start;i<candidates.length;i++){ 16 if(i>start&&candidates[i]==candidates[i-1]) continue; 17 if(candidates[i]<=target){ 18 stack.push(candidates[i]); 19 helper(candidates,i+1,target-candidates[i],stack,res); 20 stack.pop(); 21 } 22 } 23 } 24 }
3.组合总和3
回溯法
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
https://leetcode-cn.com/problems/combination-sum-iii/solution/hui-su-jian-zhi-by-liweiwei1419/
说明:
所有数字都是正整数。
解集不能包含重复的组合。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
1 class Solution { 2 public List<List<Integer>> combinationSum3(int k, int n) { 3 Stack<Integer> stack = new Stack<>(); 4 List<List<Integer>> res = new ArrayList<>(); 5 helper(k,n,1,res,stack); 6 return res; 7 } 8 public void helper(int k,int n,int start,List<List<Integer>> res, Stack<Integer> stack){ 9 if(n<0)return; 10 if(k==0){ 11 if(n==0){ 12 res.add(new ArrayList<>(stack)); 13 return; 14 } 15 return; 16 } 17 for(int i=start;i<=9;i++){ 18 if(i<=n){ 19 stack.push(i); 20 helper(k-1,n-i,i+1,res,stack); 21 stack.pop(); 22 } 23 } 24 } 25 }
4.组合总和4
给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。
动态规划
nums = [1,2,3]
dp[4] = dp[3]+dp[2]+dp[1];
nums = [1, 2, 3] target = 4 所有可能的组合为: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) 请注意,顺序不同的序列被视作不同的组合。 因此输出为 7。
1 class Solution { 2 public int combinationSum4(int[] candidates, int target) { 3 int[] dp = new int[target+1]; 4 dp[0]=1; 5 for(int i=1;i<=target;i++){ 6 for(int j=0;j<candidates.length;j++){ 7 if(i>=candidates[j]){ 8 dp[i]+=dp[i-candidates[j]]; 9 } 10 } 11 } 12 return dp[target]; 13 } 14 15 }