48
48
49
49
## 解法
50
50
51
- DFS 回溯法。需要先对 candidates 数组进行排序。
51
+ ** 方法一:排序 + 回溯 **
52
52
53
- 去重技巧:
53
+ 题目要求组合不能重复,我们可以先对数组进行排序,方便跳过重复的数字。
54
54
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$ 为数组的长度。
59
58
60
59
<!-- 这里可写通用的实现逻辑 -->
61
60
@@ -68,22 +67,23 @@ if i > u and candidates[i] == candidates[i - 1]:
68
67
``` python
69
68
class Solution :
70
69
def combinationSum2 (self , candidates : List[int ], target : int ) -> List[List[int ]]:
71
- def dfs (u , s , t ):
70
+ def dfs (i , s ):
72
71
if s > target:
73
72
return
74
73
if s == target:
75
74
ans.append(t[:])
76
75
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 ]:
79
78
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] )
82
81
t.pop()
83
82
84
83
ans = []
85
84
candidates.sort()
86
- dfs(0 , 0 , [])
85
+ t = []
86
+ dfs(0 , 0 )
87
87
return ans
88
88
```
89
89
@@ -93,33 +93,33 @@ class Solution:
93
93
94
94
``` java
95
95
class Solution {
96
- private List<List<Integer > > ans;
96
+ private List<List<Integer > > ans = new ArrayList<> ();
97
+ private List<Integer > t = new ArrayList<> ();
97
98
private int [] candidates;
98
99
private int target;
99
100
100
101
public List<List<Integer > > combinationSum2 (int [] candidates , int target ) {
101
- ans = new ArrayList<> ();
102
102
Arrays . sort(candidates);
103
103
this . target = target;
104
104
this . candidates = candidates;
105
- dfs(0 , 0 , new ArrayList<> () );
105
+ dfs(0 , 0 );
106
106
return ans;
107
107
}
108
108
109
- private void dfs (int u , int s , List< Integer > t ) {
109
+ private void dfs (int i , int s ) {
110
110
if (s > target) {
111
111
return ;
112
112
}
113
113
if (s == target) {
114
114
ans. add(new ArrayList<> (t));
115
115
return ;
116
116
}
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 ]) {
119
119
continue ;
120
120
}
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] );
123
123
t. remove(t. size() - 1 );
124
124
}
125
125
}
@@ -131,45 +131,37 @@ class Solution {
131
131
``` cpp
132
132
class Solution {
133
133
public:
134
- vector<int > candidates;
135
- vector<vector<int >> ans;
136
- vector<int > t;
137
- int target;
138
-
139
134
vector<vector<int >> combinationSum2(vector<int >& candidates, int target) {
140
135
sort(candidates.begin(), candidates.end());
141
- this->candidates = candidates;
142
- this->target = target;
136
+ vector<vector<int >> ans;
143
137
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);
145
152
return ans;
146
153
}
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
- }
161
154
};
162
155
```
163
156
164
157
### **Go**
165
158
166
159
```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) {
170
161
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) {
173
165
if s > target {
174
166
return
175
167
}
@@ -179,21 +171,56 @@ func combinationSum2(candidates []int, target int) [][]int {
179
171
ans = append(ans, cp)
180
172
return
181
173
}
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] {
184
176
continue
185
177
}
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] )
188
180
t = t[:len(t)-1]
189
181
}
190
182
}
191
-
192
- dfs(0, 0, t)
193
- return ans
183
+ dfs(0, 0)
184
+ return
194
185
}
195
186
```
196
187
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
+
197
224
### ** TypeScript**
198
225
199
226
``` ts
@@ -257,6 +284,38 @@ impl Solution {
257
284
}
258
285
```
259
286
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
+
260
319
### ** ...**
261
320
262
321
```
0 commit comments