216. Combination Sum III
Find all valid combinations of k numbers that sum up to n such that the following conditions are true:
- Only numbers 1 through 9 are used.
- Each number is used at most once.
Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.
Example 1:
Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation:1 + 2 + 4 = 7
There are no other valid combinations.
Example 2:
Input: k = 3, n = 9
Output: [[1,2,6],[1,3,5],[2,3,4]]
Explanation:1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other valid combinations.
Example 3:
Input: k = 4, n = 1
Output: []
Explanation: There are no valid combinations.Using 4 different numbers in the range [1,9], the smallest sum we can get is 1+2+3+4 = 10 and since 10 > 1, there are no valid combination.
Constraints:
- 2 <= k <= 9
- 1 <= n <= 60
From: LeetCode
Link: 216. Combination Sum III
Solution:
Ideas:
- Dynamic Capacity: The capacity for storing combinations is initially set and then doubled as needed. This prevents overflow by ensuring there's always enough space for new combinations.
- Safe Memory Operations: All memory allocations and accesses are carefully managed to ensure they stay within bounds. This includes checking capacity before adding new combinations and correctly allocating and freeing memory.
- Base Case Check: The base case in the backtrack function ensures that we only add valid combinations that meet the criteria (sum equals n and combination length equals k).
Caode:
c
void backtrack(int target, int k, int start, int* path, int depth, int*** res, int* resSize, int** colSizes, int* capacity) {
// Base case: if the combination is complete
if (depth == k) {
if (target == 0) {
// If current path sums up to n, add it to the results
if (*resSize >= *capacity) {
// Double the capacity if necessary
*capacity *= 2;
*res = realloc(*res, *capacity * sizeof(int*));
*colSizes = realloc(*colSizes, *capacity * sizeof(int));
}
(*res)[*resSize] = (int*)malloc(k * sizeof(int));
for (int i = 0; i < k; i++) {
(*res)[*resSize][i] = path[i];
}
(*colSizes)[*resSize] = k;
(*resSize)++;
}
return;
}
for (int i = start; i <= 9; i++) {
if (i > target) break; // Early termination
path[depth] = i; // Choose
backtrack(target - i, k, i + 1, path, depth + 1, res, resSize, colSizes, capacity); // Explore
// No need to explicitly "unchoose", as path[depth] will be overwritten in the next iteration
}
}
int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
int capacity = 128; // Initial capacity for results
int** res = (int**)malloc(capacity * sizeof(int*));
*returnColumnSizes = (int*)malloc(capacity * sizeof(int));
*returnSize = 0;
int* path = (int*)malloc(k * sizeof(int)); // Temp storage for the current combination
backtrack(n, k, 1, path, 0, &res, returnSize, returnColumnSizes, &capacity);
free(path); // Cleanup
return res;
}