1.组合
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
考察知识点:DFS
class Solution {
public:
vector<int> temp;
vector<vector<int>> ans;
vector<vector<int>> combine(int n, int k) {
dfs(n,k,1);
return ans;
}
void dfs(int n,int k,int start)
{
if(temp.size()==k)
{
ans.push_back(temp);
return;
}
for(int i=start;i<=n;++i)
{
temp.push_back(i);
dfs(n,k,i+1); //确保第二个数大于第一个数
temp.pop_back();
}
}
};
2.组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
说明:所有数字(包括 target)都是正整数。解集不能包含重复的组合。
考察知识点:DFS
class Solution {
public:
vector<int> temp;
vector<vector<int>> ans;
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
dfs(candidates,target,0);
return ans;
}
void dfs(vector<int>& candidates, int target,int start){
if(target<0) return; //剪枝
if(target==0)
{
ans.push_back(temp);
return;
}
for(int i=start;i<candidates.size();++i)
{
temp.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i);
temp.pop_back();
}
}
};
3.组合总和 II
给定一个数组 candidates 和一个目标数 target,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
考察知识点:DFS
class Solution {
public:
vector<int> temp;
vector<vector<int>> ans;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end()); //先排序
dfs(candidates,target,0);
return res;
}
void dfs(vector<int>& candidates, int target,int start){
if(target<0) return;
if(target==0)
{
ans.push_back(temp);
return;
}
for(int i=start;i<candidates.size();++i)
{
if(i>start&&candidates[i]==candidates[i-1]) continue; //去重
temp.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i+1); //确保下一个数比当前数大
temp.pop_back();
}
}
};
4.组合总和 III
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:所有数字都是正整数。解集不能包含重复的组合。
考察知识点:DFS
class Solution {
public:
vector<int> temp;
vector<vector<int>> ans;
vector<vector<int>> combinationSum3(int k, int n) {
dfs(k,n,1);
return ans;
}
void dfs(int k,int n,int start){
if(n==0&&k==0)
{
ans.push_back(temp);
return;
}
if(n==0||k==0) return; //剪枝
for(int i=start;i<=9;++i)
{
temp.push_back(i);
dfs(k-1,n-i,i+1); //确保下一个数比当前数大
temp.pop_back();
}
}
};
5.组合总和 Ⅳ
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。
题目数据保证答案符合 32 位整数范围。
考察知识点:动态规划
int combinationSum4(vector<int>& nums, int target) {
//dfs会超时
//使用dp数组,dp[i]代表组合数为i时使用nums中的数能组成的组合数的个数
//dp[i]=dp[i-nums[0]]+dp[i-nums[1]]+dp[i-nums[2]]+...
//举个例子比如nums=[1,3,4],target=7;dp[7]=dp[6]+dp[4]+dp[3]
//其实就是说7的组合数可以由三部分组成,1和dp[6],3和dp[4],4和dp[3]
vector<int> dp(target+1);
dp[0]=1;
for(int i=1;i<=target;++i)
{
for(int num:nums)
{
if(i>=num)
dp[i]+=dp[i-num];
}
}
return dp[target];
}