LeetCode 39. 组合总和 回溯算法+剪枝

LeetCode 39. 组合总和 回溯算法+剪枝_第1张图片

和216.组合总和III 不同之处在于这题数组中的数字可以重复使用多次,并且没有数量要求。
定义两个全局变量,result存放结果集,path存放任何条件的结果。index来指示开始的位置,length来记录每一个path数组的长度(因为每一个符合target的数组的长度不一样)。

还是一样的回溯三部曲。

  1. 参数:需要sum来计算总和和index来控制开始的位置。
  2. 终止条件:当sum==target时,以及sum>target时。
  3. 单层逻辑:从index开始搜索candidates。对比之前,递归时不用j+1,因为这题可以重复选取集合中的元素。 剪枝:jtarget时,就没必要再进入下一层递归了。
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;
}

你可能感兴趣的:(LeetCode,算法,leetcode,剪枝,回溯,组合)