原题地址:点击打开链接
这道题看了题目的提示需要使用backtracking的方法。我对backtracking的理解就是DFS,把每一种组合的可能性想象成一个Narry-Tree的root to leaf的path。才用深度优先搜索,就可以遍历每一种可能性。把有效的组合存放在一个向量里面。等到向量中的元素之和等于目标数时买就可以将此向量压入结果向量中(一个向量的向量)。代码如下。这是第二次做这道题,目的是想回顾一下DFS以及merge sort。
class Solution { // Using DFS
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
vector<vector<int> > res;
vector<int> tmp;
int sum = 0;
int idx = 0;
mergeSort(candidates, 0, candidates.size() - 1);
DFS(candidates, idx, target, sum, tmp, res);
return res;
}
void DFS(vector<int> &nums, int idx, int target, int sum, vector<int> &tmp, vector<vector<int> > &res) {
if(sum == target) {
res.push_back(tmp);
} else if(sum < target) {
int size = nums.size();
for(int i = idx; i < size; i++) {
tmp.push_back(nums[i]);
DFS(nums, i, target, sum + nums[i], tmp, res);
tmp.pop_back();
}
}
}
void merge(vector<int> &num, int start, int mid, int end){
int size1 = mid - start + 1;
int size2 = end - mid;
int idx1 = start, idx2 = mid + 1;
vector<int> tmp;
while(idx1 <= mid && idx2 <= end)
{
if(num[idx1] < num[idx2])
{
tmp.push_back(num[idx1]);
idx1++;
}
else
{
tmp.push_back(num[idx2]);
idx2++;
}
}
while(idx1 <= mid)
{
tmp.push_back(num[idx1]);
idx1++;
}
while(idx2 <= end)
{
cout<<"idx2 "<<idx2<<endl;
tmp.push_back(num[idx2]);
idx2++;
}
for(int i = start; i <= end; i++)
{
num[i]=tmp.front();
tmp.erase(tmp.begin());
}
}
void mergeSort(vector<int> &num, int start, int end){
if(start == end) return;
int mid = start + (end - start) / 2;
mergeSort(num, start, mid);
mergeSort(num, mid + 1, end);
merge(num, start, mid, end);
}
};