给定一个数组 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
int cmp(const void * a1,const void * a2)
{
return *(int *)a1-*(int *)a2;
}
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++)
{
//可以直接把组合综合II给迁移过来‘
//当然是要改一下的,针对candidate中的每个数字只能用一次只需要递归时first多加一就可以了
if(i!=first) //关键点,这是在每一层开始的时候不能用
//这句话if(candidates[i-1]==candidates[i]) continue;
{if(candidates[i-1]==candidates[i]) continue;}
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+1,path,depth,candidates,target,candidatesSize,result,size,returnColumnSizes);}
depth--;
}
}
int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
*returnColumnSizes=(int *)malloc(sizeof(int)*1000);
int path[1000];
qsort(candidates,candidatesSize,sizeof(int),cmp);
int **result=(int **)malloc(sizeof(int*)*1000);
int size=0;
dfs(0,path,0,candidates,target,candidatesSize,result,&size,*returnColumnSizes);
//删除重复数组,或是排序后将相同的数字跳过
//我采用的是删除重复数,经过实验发现这种方法不行,原因是,例1 一旦删除,1.1.6是不会产生的
*returnSize=size;
return result;
}
执行结果:
通过
显示详情
执行用时 :
12 ms
, 在所有 c 提交中击败了
71.45%
的用户
内存消耗 :
10.1 MB
, 在所有 c 提交中击败了
62.50%
的用户