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 (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7
and target 7
,
A solution set is: [7]
[2, 2, 3]
题目解析:
让在数组中找到合适的数据,让其等于给定值target。就是应用深度优先算法,选择一个元素,再递归进去。但是仅考虑到这里的话,会造成重复:223和232等。那么在下一层递归的时候,从k开始到n-1遍历。这样就不会有重复结果了。
#include <stdio.h>
#include <stdlib.h>
struct Stk{
int arr[20];
int len;
};
void Print(struct Stk *stack)
{
for(int i = 0;i < stack->len;i++){
printf("%d ",stack->arr[i]);
}
printf("\n");
}
//n-数组长度,sum剩余要求的和,递归遍历时从k索引开始遍历到n-1,避免重复,stack为栈。
void DFS(int arr[],int n,int sum,int k,struct Stk *stack)
{
for(int i = k;i < n;i++){
if(arr[i] == sum){ //当正好为剩余数的和,就先入栈,再打印,再出栈,最后返回,因为后面的数更大
stack->arr[stack->len] = arr[i];
stack->len++;
Print(stack);
stack->len--;
return;
}
if(arr[i] < sum){ //递归含义,选择后递归,然后退出,再遍历后续元素
stack->arr[stack->len++] = arr[i];
DFS(arr,n,sum-arr[i],i,stack);
stack->len--;
}else{ //当arr[i] > sum 时,就退出,不对后面更大的数进行判断。
break;
}
}
}
int main()
{
int arr[] = {2,3,6,7};
int n = sizeof(arr)/sizeof(int);
int sum;
struct Stk stack;
stack.len = 0;
while(scanf("%d",&sum)){
DFS(arr,n,sum,0,&stack);
}
return 0;
}
正统的递归方式
class Solution {
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
sort(candidates.begin(), candidates.end());
vector<int>::iterator pos = unique(candidates.begin(), candidates.end());
candidates.erase(pos, candidates.end());
vector<vector<int> > ans;
vector<int> record;
searchAns(ans, record, candidates, target, 0);
return ans;
}
private:
void searchAns(vector<vector<int> > &ans, vector<int> &record, vector<int> &candidates, int target, int idx) {
if (target == 0) {
ans.push_back(record);
return;
}
if (idx == candidates.size() || candidates[idx] > target) {
return;
}
for (int i = target / candidates[idx]; i >= 0; i--) {
record.push_back(candidates[idx]);
}
for (int i = target / candidates[idx]; i >= 0; i--) {
record.pop_back();
searchAns(ans, record, candidates, target - i * candidates[idx], idx + 1);
}
}
};