-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy path40. Combination Sum II.c
121 lines (105 loc) · 3.15 KB
/
40. Combination Sum II.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
40. Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
*/
/**
* 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().
*/
typedef struct {
int **p;
int *col;
int sz;
int n;
} res_t;
typedef struct {
int *b;
int sz;
} buff_t;
void add2buff(buff_t *buff, int d, int k) {
if (buff->sz == 0) {
buff->sz = 10;
buff->b = malloc(buff->sz * sizeof(int));
//assert(buff->b);
} else if (buff->sz == d) {
buff->sz *= 2;
buff->b = realloc(buff->b, buff->sz * sizeof(int));
//assert(buff->b);
}
buff->b[d] = k;
}
void add2res(res_t *res, int *b, int d) {
int *tmp = malloc(d * sizeof(int));
//assert(tmp);
memcpy(tmp, b, d * sizeof(int));
if (res->sz == 0) {
res->sz = 10;
res->p = malloc(res->sz * sizeof(int *));
res->col = malloc(res->sz * sizeof(int));
//assert(res->p && res->col);
} else if (res->sz == res->n) {
res->sz *= 2;
res->p = realloc(res->p, res->sz * sizeof(int *));
res->col = realloc(res->col, res->sz * sizeof(int));
//assert(res->p && res->col);
}
res->p[res->n] = tmp;
res->col[res->n] = d;
res->n ++;
}
void bt(int *cand, int sz, int target, int start, int d, buff_t *buff, res_t *res) {
int i;
if (target < 0) return; // no solution
if (target == 0) { // found it
add2res(res, buff->b, d);
return;
}
for (i = start; i < sz; i ++) {
if (i > start && cand[i] == cand[i - 1]) continue; // skip duplicated
add2buff(buff, d, cand[i]);
bt(cand, sz, target - cand[i], i + 1, d + 1, buff, res);
}
}
int cmp(const void *a, const void *b) {
int x = *(int *)a;
int y = *(int *)b;
return (x < y) ? -1 :
(x > y) ? 1 : 0;
}
int** combinationSum2(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) {
res_t res = { 0 };
buff_t buff = { 0 };
if (candidatesSize) {
qsort(candidates, candidatesSize, sizeof(int), cmp);
bt(candidates, candidatesSize, target, 0, 0, &buff, &res);
if (buff.b) free(buff.b);
}
*returnSize = res.n;
*columnSizes = res.col;
return res.p;
}
/*
Difficulty:Medium
Total Accepted:120.7K
Total Submissions:358K
Companies Snapchat
Related Topics Array Backtracking
Similar Questions
Combination Sum
*/