剪枝优化,这里剪枝优化的关键点在于,剩下还需要选d个数,倒着选,剩下选择的数的范围是[1, i],如果 i + (i - 1) + (i - 2)… + (i - d + 1) = (2 * i - d + 1) / 2,等差数列和公式,即最大的d个数,的和加起来都没有,再加上之前选择的数的值的和都达不到目标值,就可以不继续往下递归;
代码:
class Solution {
public:vector<vector<int>> combinationSum3(int k, int n) {vector<vector<int>> ans;vector<int> path;auto dfs = [&](auto&& dfs, int i, int t) {int d = k - path.size(); // 还要选 d 个数if (t < 0 || t > (i * 2 - d + 1) * d / 2) { // 剪枝优化return;}// 这是t 只能是 >= 0, d >= 0if (d == 0) { // 找到一个合法组合ans.emplace_back(path);return;}for (int j = i; j >= d; j--) {path.push_back(j);dfs(dfs, j - 1, t - j);path.pop_back();}};dfs(dfs, 9, n);return ans;}
};