题目:
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
回溯剪枝:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
private:
vector<int> tmpVec; // 引用外界的数据
vector<int> curPath; // 当前需要保存的一组数据(路径)
vector<vector<int>> retVec; // 需要返回的数
// 从第几个数字开始(避免重复的值)
// 当前需要的目标值
void DFS(int start, int curTarget) {
if (curTarget == 0) {
retVec.push_back(curPath);
return;
}
// 当前的目标有几种可能性
for (int i = start; i < tmpVec.size() && curTarget - tmpVec[i] >= 0; i++)
{
// 限制范围,舍弃当前在前一个已经判断过的数
if (i > start && tmpVec[i] == tmpVec[i - 1])
continue;
curPath.push_back(tmpVec[i]); // 将当前选择的数据加入路径中
DFS(i + 1, curTarget - tmpVec[i]); // 开始递归(从下一个数开始,移除重复的可能性)
curPath.pop_back(); // 不管成功与否,都要删除最后一个数据,继续搜索其它的可能
}
}
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
this->tmpVec = candidates;
sort(this->tmpVec.begin(), this->tmpVec.end()); // 排序,避免重复的值
DFS(0, target);
return this->retVec;
}
};
int main() {
vector<int> vec{ 10,1,2,7,6,1,5 };
vector<vector<int>> result = (new Solution())->combinationSum2(vec, 8);
for (size_t i = 0; i < result.size(); i++)
{
for (size_t j = 0; j < result[i].size(); j++)
{
cout << result[i][j] << " ";
}
cout << endl;
}
return 0;
}