【C语言刷LeetCode】40. 组合总和 II(M)

给定一个数组 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

见到数组,条件反射的考虑是否需要排序,显然这道题是需要的。

C语言排序千万不要去写两个for循环,太费代码和时间,直接用库函数qsort,那么qsort的用法就需要牢记了。

这道题另一个难点就是重复元素,原则就是第一个元素没有选,那么后面重复的元素也不选择。如果第一个元素选择了,后面的重复元素可以选择也可以不选。显然算法选择就是深搜了。

接着要注意C语言做题一个恶心的地方,returnColumnSizes参数的申请。题目给出的是一个二维数组,而实际申请内存只需要申请returnColumnSizes[0]的,returnColumnSizes[0][i]就表示返回数组第i个数组的大小。

接着才是深搜的算法,选这个元素一个分支,不选这个元素另一个深搜分支。不选这个元素,需要恢复刚选的元素。然后当target=0时,表示满足条件,需要拷贝这个临时数组到返回数组中。

最后仍是要吐槽,C语言相比其他语言做题,太吃亏了。很多时候30%的代码在申请内存,比如说这道题retarr由于是二位数组,所以需要两次malloc,temp 和 returnColumnSizes[0]也是需要申请内存的。

int count;

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

void searchpath(int* candidates, int candidatesSize, int target, int **retarr, int itend, int *temp, int num, int** returnColumnSizes) {
    int i;
    
    if (target < 0) {
        return;
    }
    
    //printf("count=%d,target=%d,temp[%d]=%d,itend=%d\n",count,target,num, temp[num],itend);

    if (target == 0) {
        retarr[count] = (int *)malloc(sizeof(int) * candidatesSize);
        
        memcpy(retarr[count], temp, sizeof(int) * num);
        returnColumnSizes[0][count] = num;
        count++;
        return;
    }

    for (i = itend; i < candidatesSize; i++){
        temp[num] = candidates[i];
        num = num + 1;
        target = target - candidates[i];
        
        searchpath(candidates, candidatesSize, target, retarr, i+1,temp,num,returnColumnSizes);

        // 不选
        num = num - 1;
        temp[num] = 0;
        target = target + candidates[i];

        // 重复的元素,第一个没有选,第二个也不选
        while (((i + 1) != candidatesSize) && (candidates[i] == candidates[i + 1])) {
            i++;
        }

    }
}

int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    int **retarr;
    int i;
    int j;
    int k;
    
    int *temp;
    int line = 0;
    int num = 0;
    int colnum = 0;
    
    count = 0;
    
    qsort(candidates, candidatesSize, sizeof(int), comp);
    
    retarr = (int **)malloc(sizeof(int *) * 8096);
    
    returnColumnSizes[0] = (int *)malloc(sizeof(int) * 8096);
    temp = (int *)malloc(sizeof(int) * candidatesSize);
    
    memset(temp, 0, sizeof(int) * candidatesSize);
    
    searchpath(candidates, candidatesSize, target, retarr, 0, temp, 0, returnColumnSizes);
    
    *returnSize = count;
    
    return retarr;
}
发布了102 篇原创文章 · 获赞 17 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jin615567975/article/details/104323305
今日推荐