@@ -194,3 +194,54 @@ public:
194
194
}
195
195
};
196
196
```
197
+
198
+ ## 组合总和II https://leetcode-cn.com/problems/combination-sum-ii/
199
+ 给你一个由候选元素组成的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
200
+
201
+ candidates 中的每个元素在每个组合中只能使用 一次 。
202
+
203
+ 注意:解集不能包含重复的组合。
204
+
205
+ 来源:力扣(LeetCode)
206
+ 链接:https://leetcode-cn.com/problems/combination-sum-ii
207
+ 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
208
+
209
+ 思路:
210
+
211
+ 组合II 递归三部曲
212
+ - used[ i - 1] == true,说明同一树枝candidates[ i - 1] 使用过
213
+ - used[ i - 1] == false,说明同一树层candidates[ i - 1] 使用过
214
+ - 要对同一树层使用过的元素进行跳过
215
+
216
+ 参考卡神思路:https://programmercarl.com/0040.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CII.html#%E5%9B%9E%E6%BA%AF%E4%B8%89%E9%83%A8%E6%9B%B2
217
+
218
+ class Solution {
219
+ public:
220
+ std::vector< std::vector<int > > ret;
221
+ std::vector<int > path;
222
+ vector<vector<int >> combinationSum2(vector<int >& candidates, int target) {
223
+ std::vector<bool > used(candidates.size(),false);
224
+ ret.clear();
225
+ path.clear();
226
+ std::sort(candidates.begin(), candidates.end());
227
+ backtrack(candidates, 0, 0, target, used);
228
+ return ret;
229
+ }
230
+ void backtrack(vector<int >& candidates,int sum, int start_index, int target, std::vector<bool >& used) {
231
+ if (sum == target) {
232
+ ret.push_back(path);
233
+ return;
234
+ }
235
+
236
+ for (int i = start_index; i < candidates.size() && sum + candidates[ i] <= target ; ++i) {
237
+ if ( i > 0 && candidates[ i] == candidates[ i - 1] && used[ candidates[ i - 1]] == false) continue;
238
+ sum += candidates[ i] ;
239
+ used[ candidates[ i]] = true;
240
+ path.push_back(candidates[ i] );
241
+ backtrack(candidates, sum, i + 1, target, used);//每个数只能用一次
242
+ path.pop_back();
243
+ used[ candidates[ i]] = false;
244
+ sum -= candidates[ i] ;
245
+ }
246
+ }
247
+ };
0 commit comments