leetcode做题笔记40

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

思路一:回溯

int cmp(const void* a, const void* b){
    return *(int*)a - *(int*)b;
}

int** Result = NULL;
int* rtcolsizes = NULL;
int Result_Index = 0;

int Path[30] = {0};
int Path_Index = 0;

int* Source = NULL;
int Source_Size = 0;

void Back_Track(int target, int idx){
    if(target == 0){
        int* temi = (int*)malloc(sizeof(int) * Path_Index);
        memcpy(temi, Path, Path_Index * sizeof(int));
        Result[Result_Index] = temi;
        rtcolsizes[Result_Index] = Path_Index;
        Result_Index++;
        return;
    }

    for(int i = idx; i < Source_Size; i++){
        if(i > idx && Source[i] == Source[i - 1]){
            continue;
        }
        if(target - Source[i] < 0){
            break;
        }
        Path[Path_Index] = Source[i];
        Path_Index++;
        Back_Track(target - Source[i], i + 1);
        Path_Index--;
    }
}

int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    qsort(candidates, candidatesSize, sizeof(int), cmp);
    Result = (int**)malloc(sizeof(int*) * 48);
    rtcolsizes = (int*)malloc(sizeof(int) * 48);
    Result_Index = 0;
    Path_Index = 0;
    Source = candidates;
    Source_Size = candidatesSize;
    Back_Track(target, 0);
    *returnSize = Result_Index;
    *returnColumnSizes = rtcolsizes;
    return Result;
}

分析:

该题要求和为target的组合,可先将原数组排序后进行递归回溯处理。将数组中目标数不断减去小于目标数的数,直到等于0时将这些存储到准备好的数组中,再返回数组。实际编写的时候需注意加的数的赋给result的时候要path存储加的数。

总结:

本题主要考察了回溯算法的应用,使用递归将加的组合数找出。

你可能感兴趣的:(回溯,leetcode,笔记,算法)