Skip to content

Commit 705a881

Browse files
committed
feat: add solutions to lc problem: No.0040
No.0040.Combination Sum II
1 parent 03ae32e commit 705a881

File tree

11 files changed

+315
-229
lines changed

11 files changed

+315
-229
lines changed

solution/0000-0099/0040.Combination Sum II/README.md

+113-54
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@
4848

4949
## 解法
5050

51-
DFS 回溯法。需要先对 candidates 数组进行排序。
51+
**方法一:排序 + 回溯**
5252

53-
去重技巧:
53+
题目要求组合不能重复,我们可以先对数组进行排序,方便跳过重复的数字。
5454

55-
```python
56-
if i > u and candidates[i] == candidates[i - 1]:
57-
continue
58-
```
55+
然后从左到右遍历数组,每次遍历到一个数,就将其加入到当前组合中,然后继续遍历下一个数,直到当前组合的和等于目标值,此时将当前组合加入到结果集中,然后回溯到上一层,继续遍历下一个数。
56+
57+
时间复杂度 $O(2^n \times n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
5958

6059
<!-- 这里可写通用的实现逻辑 -->
6160

@@ -68,22 +67,23 @@ if i > u and candidates[i] == candidates[i - 1]:
6867
```python
6968
class Solution:
7069
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
71-
def dfs(u, s, t):
70+
def dfs(i, s):
7271
if s > target:
7372
return
7473
if s == target:
7574
ans.append(t[:])
7675
return
77-
for i in range(u, len(candidates)):
78-
if i > u and candidates[i] == candidates[i - 1]:
76+
for j in range(i, len(candidates)):
77+
if j > i and candidates[j] == candidates[j - 1]:
7978
continue
80-
t.append(candidates[i])
81-
dfs(i + 1, s + candidates[i], t)
79+
t.append(candidates[j])
80+
dfs(j + 1, s + candidates[j])
8281
t.pop()
8382

8483
ans = []
8584
candidates.sort()
86-
dfs(0, 0, [])
85+
t = []
86+
dfs(0, 0)
8787
return ans
8888
```
8989

@@ -93,33 +93,33 @@ class Solution:
9393

9494
```java
9595
class Solution {
96-
private List<List<Integer>> ans;
96+
private List<List<Integer>> ans = new ArrayList<>();
97+
private List<Integer> t = new ArrayList<>();
9798
private int[] candidates;
9899
private int target;
99100

100101
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
101-
ans = new ArrayList<>();
102102
Arrays.sort(candidates);
103103
this.target = target;
104104
this.candidates = candidates;
105-
dfs(0, 0, new ArrayList<>());
105+
dfs(0, 0);
106106
return ans;
107107
}
108108

109-
private void dfs(int u, int s, List<Integer> t) {
109+
private void dfs(int i, int s) {
110110
if (s > target) {
111111
return;
112112
}
113113
if (s == target) {
114114
ans.add(new ArrayList<>(t));
115115
return;
116116
}
117-
for (int i = u; i < candidates.length; ++i) {
118-
if (i > u && candidates[i] == candidates[i - 1]) {
117+
for (int j = i; j < candidates.length; ++j) {
118+
if (j > i && candidates[j] == candidates[j - 1]) {
119119
continue;
120120
}
121-
t.add(candidates[i]);
122-
dfs(i + 1, s + candidates[i], t);
121+
t.add(candidates[j]);
122+
dfs(j + 1, s + candidates[j]);
123123
t.remove(t.size() - 1);
124124
}
125125
}
@@ -131,45 +131,37 @@ class Solution {
131131
```cpp
132132
class Solution {
133133
public:
134-
vector<int> candidates;
135-
vector<vector<int>> ans;
136-
vector<int> t;
137-
int target;
138-
139134
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
140135
sort(candidates.begin(), candidates.end());
141-
this->candidates = candidates;
142-
this->target = target;
136+
vector<vector<int>> ans;
143137
vector<int> t;
144-
dfs(0, 0, t);
138+
function<void(int, int)> dfs = [&](int i, int s) {
139+
if (s > target) return;
140+
if (s == target) {
141+
ans.emplace_back(t);
142+
return;
143+
}
144+
for (int j = i; j < candidates.size(); ++j) {
145+
if (j > i && candidates[j] == candidates[j - 1]) continue;
146+
t.emplace_back(candidates[j]);
147+
dfs(j + 1, s + candidates[j]);
148+
t.pop_back();
149+
}
150+
};
151+
dfs(0, 0);
145152
return ans;
146153
}
147-
148-
void dfs(int u, int s, vector<int>& t) {
149-
if (s > target) return;
150-
if (s == target) {
151-
ans.push_back(t);
152-
return;
153-
}
154-
for (int i = u; i < candidates.size(); ++i) {
155-
if (i > u && candidates[i] == candidates[i - 1]) continue;
156-
t.push_back(candidates[i]);
157-
dfs(i + 1, s + candidates[i], t);
158-
t.pop_back();
159-
}
160-
}
161154
};
162155
```
163156
164157
### **Go**
165158
166159
```go
167-
func combinationSum2(candidates []int, target int) [][]int {
168-
var ans [][]int
169-
var t []int
160+
func combinationSum2(candidates []int, target int) (ans [][]int) {
170161
sort.Ints(candidates)
171-
var dfs func(u, s int, t []int)
172-
dfs = func(u, s int, t []int) {
162+
t := []int{}
163+
var dfs func(i, s int)
164+
dfs = func(i, s int) {
173165
if s > target {
174166
return
175167
}
@@ -179,21 +171,56 @@ func combinationSum2(candidates []int, target int) [][]int {
179171
ans = append(ans, cp)
180172
return
181173
}
182-
for i := u; i < len(candidates); i++ {
183-
if i > u && candidates[i] == candidates[i-1] {
174+
for j := i; j < len(candidates); j++ {
175+
if j > i && candidates[j] == candidates[j-1] {
184176
continue
185177
}
186-
t = append(t, candidates[i])
187-
dfs(i+1, s+candidates[i], t)
178+
t = append(t, candidates[j])
179+
dfs(j+1, s+candidates[j])
188180
t = t[:len(t)-1]
189181
}
190182
}
191-
192-
dfs(0, 0, t)
193-
return ans
183+
dfs(0, 0)
184+
return
194185
}
195186
```
196187

188+
### **JavaScript**
189+
190+
```js
191+
/**
192+
* @param {number[]} candidates
193+
* @param {number} target
194+
* @return {number[][]}
195+
*/
196+
var combinationSum2 = function (candidates, target) {
197+
candidates.sort((a, b) => a - b);
198+
const n = candidates.length;
199+
const t = [];
200+
const ans = [];
201+
const dfs = (i, s) => {
202+
if (s > target) {
203+
return;
204+
}
205+
if (s === target) {
206+
ans.push([...t]);
207+
return;
208+
}
209+
for (let j = i; j < n; j++) {
210+
const num = candidates[j];
211+
if (j > i && num === candidates[j - 1]) {
212+
continue;
213+
}
214+
t.push(num);
215+
dfs(j + 1, s + num);
216+
t.pop();
217+
}
218+
};
219+
dfs(0, 0);
220+
return ans;
221+
};
222+
```
223+
197224
### **TypeScript**
198225

199226
```ts
@@ -257,6 +284,38 @@ impl Solution {
257284
}
258285
```
259286

287+
### **C#**
288+
289+
```cs
290+
public class Solution {
291+
public IList<IList<int>> CombinationSum2(int[] candidates, int target) {
292+
Array.Sort(candidates);
293+
var ans = new List<IList<int>>();
294+
var t = new List<int>();
295+
dfs(candidates, 0, 0, target, t, ans);
296+
return ans;
297+
}
298+
299+
private void dfs(int[] candidates, int i, int s, int target, IList<int> t, IList<IList<int>> ans) {
300+
if (s > target) {
301+
return;
302+
}
303+
if (s == target) {
304+
ans.Add(new List<int>(t));
305+
return;
306+
}
307+
for (int j = i; j < candidates.Length; ++j) {
308+
if (j > i && candidates[j] == candidates[j - 1]) {
309+
continue;
310+
}
311+
t.Add(candidates[j]);
312+
dfs(candidates, j + 1, s + candidates[j], target, t, ans);
313+
t.RemoveAt(t.Count - 1);
314+
}
315+
}
316+
}
317+
```
318+
260319
### **...**
261320

262321
```

0 commit comments

Comments
 (0)