dp思路不行,会出现重复组合数,
例如
[3,1,3,5,1,1]\n8,
[4,4,2,1,4,2,2,1,3]\n6,
这种要求路径的问题,先考虑贪心+dfs了。
WA的dp代码:
/*
* @lc app=leetcode id=40 lang=cpp
*
* [40] Combination Sum II
*/
// @lc code=start
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
int N = candidates.size();
sort(candidates.begin(),candidates.end());
vector<vector<int>> V(target+1);
vector<int> dp(target+1,0);
dp[0] = 1;
for(int i=0;i<N;i++){
if(candidates[i] > target) break;
for(int j=target-candidates[i];j>=0;j--){
if(dp[j] > 0){
int next = j+candidates[i];
dp[next] += dp[j];
int l = V[next].size();
if(l == 0 || (l > 0 && V[next][l-1] != j)){
V[next].push_back(j);
}
}
}
}
/*
for(int i=0;i<=target;i++){
printf("%d : ",i);
for(int j=0;j<V[i].size();j++){
printf("%d ",V[i][j]);
}
printf("\n");
}
*/
vector<vector<int>> ans;
vector<int> path;
dfs(ans,V,path,target);
return ans;
}
void dfs(vector<vector<int>>& ans,vector<vector<int>>& V,vector<int>& path,int level){
if(level == 0){
ans.push_back(path);
return ;
}
for(int i=0;i<V[level].size();i++){
int now = level - V[level][i];
int l = path.size();
if(l == 0 || (l > 0 && path[l-1] >= now)){
path.push_back(now);
dfs(ans,V,path,V[level][i]);
path.pop_back();
}
}
}
};
// @lc code=end
贪心+dfs代码:
/*
* @lc app=leetcode id=40 lang=cpp
*
* [40] Combination Sum II
*/
// @lc code=start
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
vector<vector<int>> ans;
vector<int> path;
dfs(ans,candidates,path,0,candidates.size(),target);
return ans;
}
void dfs(vector<vector<int>>& ans,vector<int>& c,vector<int>& path,int L,int R,int K){
if(K == 0){
ans.push_back(path);
return ;
}
if(K < 0 || L >= R) return ;
for(int i=L;i<R;i++){
path.push_back(c[i]);
dfs(ans,c,path,i+1,R,K-c[i]);
path.pop_back();
while(i+1<R && c[i+1] == c[i]) i++;
}
}
};
// @lc code=end