言归正传,这一系列的题目大体框架是给你一个数组和一个目标数,要求让我们从所给数组中挑选出一些列数字相加的和恰好等于目标数的排列数,当然了,其中加点限制是不可避免的。
I. 限制条件:可以重复抽取同一数字,但是重复的排列不算数。比较简单的回溯,对于每个nums中的数字,两种选择,放或者不放,依次递归就行了,代码如下:
点击(此处)折叠或打开
- vector<vector<int>> combinationSum(vector<int>& candidates, int target){
- int len = candidates.size();
- vector<vector<int>> res;
- if(len == 0) return res;
- sort(candidates.begin(), candidates.end());
- vector<int> combo;
- helper(candidates, target, combo, 0, len-1, res);
- return res;
- }
- void helper(vector<int>& candidates, int target, vector<int>& combo, int start, int end, vector<vector<int> > &res){
- if(target == 0){
- res.push_back(combo);
- return;
- }
- for(int i = start; i <= end&&target>=candidates[i];i++){
- combo.push_back(candidates[i]);
- helper(candidates, target-candidates[i], combo, i, end, res);
- combo.pop_back();
- }
- }
II.限制条件:每一个在nums数组中的数,最多只能放一次。思路同上,代码如下:
点击(此处)折叠或打开
- vector<vector<int>> combinationSum2(vector<int>& candidates, int target){
- int len = candidates.size();
- vector<vector<int>> res;
- if(len == 0) return res;
- sort(candidates.begin(), candidates.end());
- vector<int> combo;
- helper2(candidates, target, combo, 0, len-1, res);
- return res;
- }
- void helper2(vector<int>& candidates, int target, vector<int>& combo, int start, int end, vector<vector<int> > &res){
- if(target == 0){
- res.push_back(combo);
- return;
- }
- for(int i = start; i <= end&&target>=candidates[i];i++){
- if(i==start || candidates[i]!=candidates[i-1])// avoid repeat results
- {
- combo.push_back(candidates[i]);
- helper2(candidates, target-candidates[i], combo, i+1, end, res);
- combo.pop_back();
- }
- }
- }
点击(此处)折叠或打开
- vector<vector<int>> combinationSum3(int k, int n){
- int need = k, target = n;
- vector<vector<int>> res;
- vector<int> combo;
- if(n==0)return res;
- helper3(res, combo, target, 1, need);
- return res;
- }
- void helper3(vector<vector<int>>& res, vector<int> &combo, int target,int start, int need){
- if(target == 0&& need ==0){
- res.push_back(combo);
- return;
- }
- if(need == 0) return;
- for(int i = start; i <=9&&target>=i&&target<=need*9-need*(need-1)/2; i++){
- combo.push_back(i);
- helper3(res, combo, target-i, i+1, need-1);
- combo.pop_back();
- }
- }
点击(此处)折叠或打开
- int combinationSum4(vector<int>& nums, int target){
- int len = nums.size(), i, j;
- if(len == 0) return 0;
- vector<int> dp(target+1);
- dp[0] = 1;
- for(i = 1; i <= target; i++){
- for(j = 0; j < len; j++){
- if(i >= nums[j]) dp[i]+=dp[i-nums[j]];
- }
- }
- return dp[target];
- }