文章目录
1、组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
cpp
class Solution {
public:
vector<vector<int>> ret;
int n,k;
vector<int> path;
vector<vector<int>> combine(int _n, int _k) {
n=_n;
k=_k;
dfs(1);
return ret;
}
void dfs(int begin)
{
if(path.size()==k)
{
ret.push_back(path);
return ;
}
for(int i=begin;i<=n;i++)
{
path.push_back(i);
dfs(i+1);
path.pop_back();//恢复现场
}
}
};
2、目标和
给你一个非负整数数组 nums 和一个整数 target 。
向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
cpp
class Solution {
public:
int aim;
int ret=0;
int findTargetSumWays(vector<int>& nums, int target) {
aim=target;
dfs(nums,0,0);
return ret;
}
void dfs(vector<int> &nums,int pos,int target)
{
if(pos==nums.size())
{
if(target==aim) ret++;
return ;
}
dfs(nums,pos+1,target+nums[pos]);
dfs(nums,pos+1,target-nums[pos]);
}
};
3、组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
cpp
class Solution {
public:
vector<vector<int>> ret;
vector<int> path;
//int sum;
int target;
vector<vector<int>> combinationSum(vector<int>& candidates, int _target) {
target=_target;
dfs(candidates,0,0);
return ret;
}
void dfs(vector<int>& candidates,int begin,int sum)
{
if(sum==target)
{
ret.push_back(path);
return ;
}
else if(sum>target)
return ;
//方法一
// for(int i=begin;i<candidates.size();i++)
// {
// path.push_back(candidates[i]);
// //sum+=candidates[i];
// dfs(candidates,i,sum+candidates[i]);
// path.pop_back();
// //sum-=candidates[i];
// }
//方法二
for(int k=0;k*candidates[begin]+sum<=target;k++)
{
if(k) path.push_back(candidates[begin]);
dfs(candidates,begin+1,sum+k*candidates[begin]);
}
for(int k=1;k*candidates[begin]+sum<=target;k++)
{
path.pop_back();
}
}
};
4、字母大小写全排列
给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。
返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。
cpp
class Solution {
public:
string path;
vector<string> ret;
int n;
char change(char ch)
{
if(ch>='a'&&ch<='z') ch-=32;
else ch+=32;
return ch;
}
vector<string> letterCasePermutation(string s) {
n=s.size();
dfs(s,0);
return ret;
}
void dfs(string &s,int pos)
{
if(pos==n)
{
ret.push_back(path);
return ;
}
char ch=s[pos];
//不改变
path.push_back(s[pos]);
dfs(s,pos+1);
path.pop_back();
if(ch<'0'||ch>'9')
{
char tmp=change(ch);
path.push_back(tmp);
dfs(s,pos+1);
path.pop_back();
}
}
};
5、优美的排列
假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :
perm[i] 能够被 i 整除
i 能够被 perm[i] 整除
给你一个整数 n ,返回可以构造的 优美排列 的 数量 。
cpp
class Solution {
public:
bool check[16];
int sum=0;
int countArrangement(int n) {
dfs(n,1);
return sum;
}
void dfs(int n,int pos)
{
if(n+1==pos)
{
sum++;
return ;
}
for(int i=1;i<=n;i++)
{
if(pos%i==0||i%pos==0)
{
if(check[i]==false)
{
check[i]=true;
dfs(n,pos+1);
check[i]=false;
}
}
}
}
};