题目:给定一个候选人编号的集合 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合
这个题的特点就是不能包含重复的组合,示例1
输入: candidates =[10,1,2,7,6,1,5]
, target =8
, 输出: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
那么,用之前的算法可能[1,2,5]和[2, 1, 5]都出现在结果里,没为了不重复的选取相同的数字,首先先给数组排序,排序就可以方便找到相同的数字,假如排序后的数组有n个相同的数字,那么如果选取了m个,以后发现符合target或者已经超过目标,那么久回溯,回溯以后选取下一个数,就不能是这个相同的数,就排到n+1个数的位置
int *path;
int pathTop;
int **ans;
int ansTop;
int *colsize;
int cmp(const int* a, const int *b){
return (*(a) - (*b));
}
void backstrcking(int* candidates, int size, int target, int startIndex){
if(target == 0){
int *temp = malloc(sizeof(int) *pathTop);
for(int i = 0; i < pathTop; i++){
temp[i] = path[i];
}
colsize[ansTop] = pathTop;
ans[ansTop++] = temp;
return;
}else if(target < 0) {
return;
}
for(int j = startIndex; j < size; j++){
path[pathTop++] = candidates[j];
target -= candidates[j];
backstrcking(candidates, size, target, j + 1);
while(j < (size-1) && candidates[j] == candidates[j+1]){
j++;
}
target += candidates[j];
pathTop--;
}
}
int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
qsort(candidates, candidatesSize, sizeof(int), cmp);
path = (int*)malloc(sizeof(int) * candidatesSize);
pathTop = 0;
ans = (int**)malloc(sizeof(int*) * 10000);
ansTop = 0;
colsize = (int*)malloc(sizeof(int) * 10000);
int size = candidatesSize;
backstrcking(candidates, size, target, 0);
*returnSize = ansTop;
*returnColumnSizes = malloc(sizeof(int) *ansTop);
for(int i = 0; i < ansTop; i++){
(*returnColumnSizes)[i] = colsize[i];
}
return ans;
}