一、题目
二、题解
与组合总数1相比本题要求元素不可重复使用,此时可以维护一个check【i】数组,如果当前值没有被选择则可以选择他进行枚举,如果出现重复元素,如果重复的元素已经在前几层dfs被选择过那么当前元素可以被选择作为当前位置的值,如果没有则不能选择
class Solution {
public:
vector<vector<int>> res; // 记录结果集
vector<int> path, a; // path为dfs过程中记录路径, a为candidate全局化
int n, sum, t, check[101]; // n是元素个数,sum记录dfs过程中路径组合,check用于标记每个位置元素是否被选择
void dfs(int u) {
if (sum > t) return;
for (int i = u; i < n; i++) {
if (i != 0 && a[i - 1] == a[i] && !check[i - 1]) continue; // 如果重复且重复元素在直接的dfs中没有被选择,就不选择他
if (!check[i]) {
sum += a[i];
check[i] = 1;
path.push_back(a[i]);
if (sum == t) res.push_back(path);
else dfs(i);
check[i] = 0;
sum -= a[i];
path.pop_back();
}
}
}
void qsort(int l, int r) {
if (l > r) return;
srand(time(0));
int i = l, s = l - 1, e = r + 1, x = a[rand() % (r - l + 1) + l];
while (i < e)
if (a[i] > x) swap(a[i], a[--e]);
else if (a[i] < x) swap(a[i++], a[++s]);
else i++;
qsort(l, s), qsort(e, r);
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
// sort(candidates.begin(), candidates.end());
a = candidates;
n = a.size(), t = target;
qsort(0, n - 1); // 快排
dfs(0);
return res;
}
};