LeetCode 40. 組合總和 II Combination Sum II(C語言)
阿新 • • 發佈:2018-12-24
題目描述:
給定一個數組 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]
]
題目解答:
方法1:回溯
因為有重複元素,所以需要先排序,後邊方便跳過重複元素。
執行時間4ms,程式碼如下。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *columnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
void combine(int *** result, int* size, int* nums, int n, int target, int** column, int* before, int bef, int sum, int start) {
if(sum == target) {
(*size)++;
result[0] = (int**)realloc(result[0], *size * sizeof(int*));
result[0][*size - 1] = (int*)malloc(bef * sizeof(int));
column[0] = (int*)realloc(column[0], *size * sizeof(int));
column[0][*size - 1] = bef;
memcpy(result[0][*size - 1], before, sizeof(int) * bef);
return ;
}
int i = 0;
for(i = start; i < n; i++) {
if(sum + nums[i] > target)
continue;
before[bef] = nums[i];
combine(result, size, nums, n, target, column, before, bef + 1, sum + nums[i], i + 1);
while(i + 1 < n && nums[i] == nums[i + 1])
i++;
}
}
int comp(const void* a, const void* b) {
return *(int*)a - *(int*)b;
}
int** combinationSum2(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) {
int** result = NULL;
qsort(candidates, candidatesSize, sizeof(int), comp);
int* before = (int*)malloc(100 * sizeof(int));
combine(&result, returnSize, candidates, candidatesSize, target, columnSizes, before, 0, 0, 0);
free(before);
return result;
}