和216.组合总和III 不同之处在于这题数组中的数字可以重复使用多次,并且没有数量要求。
定义两个全局变量,result存放结果集,path存放任何条件的结果。index来指示开始的位置,length来记录每一个path数组的长度(因为每一个符合target的数组的长度不一样)。
还是一样的回溯三部曲。
- 参数:需要sum来计算总和和index来控制开始的位置。
- 终止条件:当sum==target时,以及sum>target时。
- 单层逻辑:从index开始搜索candidates。对比之前,递归时不用j+1,因为这题可以重复选取集合中的元素。 剪枝:j<candidatesSize && sum<=target。当sum>target时,就没必要再进入下一层递归了。
int *path;
int pathTop;
int **result;
int resultTop;
int *length;
void backTrack(int *candidates,int candidatesSize,int target, int sum , int index){
if(sum>target)
return ;
if(sum == target){
int *temp = malloc(sizeof(int)*pathTop);
for(int i=0;i<pathTop;i++){
temp[i] = path[i];
}
result[resultTop] = temp;
length[resultTop++] = pathTop;
return ;
}
for(int j=index; j<candidatesSize && sum<=target;j++){
sum = sum + candidates[j];
path[pathTop++] = candidates[j];
backTrack(candidates,candidatesSize,target,sum,j);
sum = sum - candidates[j];
pathTop--;
}
}
int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
pathTop = resultTop = 0;
path = malloc(sizeof(int)*100);
result = malloc(sizeof(int*) *500);
length = malloc(sizeof(int) *500);
backTrack(candidates,candidatesSize,target,0,0);
*returnSize = resultTop;
*returnColumnSizes = malloc(sizeof(int) *500);
for(int i =0 ; i<resultTop ; i++){
(*returnColumnSizes)[i] = length[i];
}
return result;
}