给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target
的组合。candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。 解集不能包含重复的组合。 示例 1:
输入: candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ] 示例
2:输入: candidates = [2,3,5], target = 8, 所求解集为: [ [2,2,2,2], [2,3,3],
[3,5] ]来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
非常常规的递归回溯,只是有两个条件特殊,1.数字可以重复2.组合不能重复
将这两点解决办法加入到代码框架中就可以了
对于1,好说,每一层递归的数字还是那几个数字,如示例一在选择了2的基础上,还能再选2.3.6.7
这时肯定有重复,如2.3.2和3.2.2
就用到2的解决办法,对于重复的组合,无非是因为之前用过的数字后面的子树再次使用导致的,即第一层中四棵树,2的子树,3的子树。。。,3的子树就不要再出现2了,即选了3后,可以选的是3.6.7。
当然对于第二个问题还有其他的解决方法
放个链接自己看领扣题解
代码放上
void dfs(int first,int *path,int depth,int *candidates,int target,int candidatesSize,int **result,int *size,int *returnColumnSizes)
{
for(int i=first;i<candidatesSize;i++)
{
if(candidates[i]>target) continue;
path[depth]=candidates[i];
depth++;
int sum=0;
for(int j=0;j<depth;j++)
{
sum=sum+path[j];
}
if(sum==target)
{
result[*size]=(int *)malloc(sizeof(int)*depth);
for(int i=0;i<depth;i++)
{
result[*size][i]=path[i];
}
returnColumnSizes[*size]=depth;
*size=*size+1;
}
if(sum<target){
dfs(i,path,depth,candidates,target,candidatesSize,result,size,returnColumnSizes);}
depth--;
}
}
int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
*returnColumnSizes=(int *)malloc(sizeof(int)*1000);
int path[1000];
int **result=(int **)malloc(sizeof(int*)*1000);
int size=0;
dfs(0,path,0,candidates,target,candidatesSize,result,&size,*returnColumnSizes);
*returnSize=size;
return result;
}
执行结果:
通过
显示详情
执行用时 :
12 ms
, 在所有 c 提交中击败了
91.30%
的用户
内存消耗 :
10.6 MB
, 在所有 c 提交中击败了
82.86%
的用户