(i)
【题目描述】Given a set of candidate numbers ( C ) and a target number ( T ), find all unique combinations in C where the candidate numbers sums to T .
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a 1, a 2, … , a k) must be in non-descending order. (ie, a 1 ≤ a 2 ≤ … ≤ a k).
The solution set must not contain duplicate combinations.
For example, given candidate set2,3,6,7and target7,
A solution set is:
[7]
[2, 2, 3]
【解题思路】dfs
【考查内容】查找,深度搜索
class Solution {
private:
vector<vector<int>> ans;
vector<int> rs;
public:
void dfs(int nowIndex,int nowSum, vector<int> cand, int candSize, int target)
{
if (nowSum > target)
return;
if (nowSum == target)
{
ans.push_back(rs);
return;
}
for (int i = nowIndex; i < candSize; i++){
if (nowSum + cand[i] <= target) // 因为cand是排序好的,显然会有大量的重复,应该避免,相当于剪枝
{
rs.push_back(cand[i]);
dfs(i, nowSum + cand[i], cand, candSize, target);
rs.pop_back();// 回溯
}
else
continue;
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
int len = candidates.size();
if (len == 0)
return ans;
sort(candidates.begin(), candidates.end());// 排序
dfs(0,0, candidates,len, target);
return ans;
}
};
(ii)
【题目描述】Given a collection of candidate numbers ( C ) and a target number ( T ), find all unique combinations in C where the candidate numbers sums to T .
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a 1, a 2, … , a k) must be in non-descending order. (ie, a 1 ≤ a 2 ≤ … ≤ a k).
The solution set must not contain duplicate combinations.
For example, given candidate set10,1,2,7,6,1,5and target8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
【解题思路】在上一题的基础上,保证数组中的每个数字不能够重复计算,所以需要设计去重的功能,在dfs时做了修改,发现仍然重复,所以有用到了c++stl map结构去重
【考查内容】查找,深度搜索
class Solution {
private:
map<vector<int>, int> mp;
vector<vector<int>> ans;
vector<int> rs;
public:
void dfs(int nowIndex,int nowSum, vector<int> cand, int candSize, int target)
{
if (nowSum > target)
return;
if (nowSum == target)
{
// 因为仍然会有重复,利用map/set去重
if (mp[rs] == 0)
{
ans.push_back(rs);
mp[rs] = 1;
}
return;
}
// 从当前的下一个开始,不包括自己,因为每个数组中的数字
for (int i = nowIndex + 1; i < candSize; i++){
if (nowSum + cand[i] <= target) // 因为cand是排序好的,显然会有大量的重复,应该避免,相当于剪枝
{
rs.push_back(cand[i]);
dfs(i, nowSum + cand[i], cand, candSize, target);
rs.pop_back();// 回溯
}
else
continue;
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
int len = candidates.size();
if (len == 0)
return ans;
sort(candidates.begin(), candidates.end());// 排序
dfs(-1,0, candidates,len, target);
return ans;
}
};