组合问题
77. 组合
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2输出:[ [2,4], [3,4],[2,3],[1,2],[1,3],[1,4],]
class Solution {
List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
List<Integer> c=new ArrayList<>();
helper(n,k,1,c);
return res;
}
public void helper(int n,int k,int start,List<Integer> c)
{
if(c.size()==k)
{
List<Integer> temp=new ArrayList<>(c);
res.add(temp);
return ;
}
if()
for(int i=start;i<=n-(k-c.size())+1;i++)
{
c.add(i);
helper(n,k,i+1,c);
c.remove(c.size()-1);
}
return ;
}
}
39. 组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:所有数字(包括 target)都是正整数。 解集不能包含重复的组合。
class Solution {
private List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<Integer> list=new ArrayList<>();
helper(candidates,0,target,list);
return res;
}
public void helper(int[] nums,int start,int target,List<Integer> list)
{
if(target==0)
{
res.add(new ArrayList<>(list));
return ;
}
for(int i=start;i<nums.length&&nums[i]<=target;i++)
{
list.add(nums[i]);
target-=nums[i];
helper(nums,i,target,list);
target+=nums[i];
list.remove(list.size()-1);
}
return ;
}
}
40. 组合总和 II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
class Solution {
private List<List<Integer>> res=new ArrayList<>();
private boolean[] used;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
used=new boolean[candidates.length];
List<Integer> list=new ArrayList<>();
helper(candidates,0,target,list);
return res;
}
public void helper(int[] nums,int start,int target,List<Integer> list)
{
if(target==0)
{
res.add(new ArrayList<>(list));
return ;
}
for(int i=start;i<nums.length&&nums[i]<=target;i++)
{
if(i>0&&nums[i-1]==nums[i]&&used[i-1]==false)
continue;
list.add(nums[i]);
target-=nums[i];
used[i]=true;
helper(nums,i+1,target,list);
target+=nums[i];
list.remove(list.size()-1);
used[i]=false;
}
return ;
}
}
216. 组合总和 III
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。 解集不能包含重复的组合。
class Solution {
private List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
if(n>45)
return res;
List<Integer> list=new ArrayList<>();
helper(k,n,1,list);
return res;
}
public void helper(int k,int n,int start,List<Integer> list)
{
if(k==0&&n==0)
{
res.add(new ArrayList<>(list));
return ;
}
if(k<0||n<0)
return ;
for(int i=start;i<=9;i++)
{
list.add(i);
helper(k-1,n-i,i+1,list);
list.remove(list.size()-1);
}
return ;
}
}