对于dfs搜索,每次for循环一组数字,我们选其中一个进行搜索,按他搜索过后记得要回溯,选择其他的进行搜索。
所以说,对于一次dfs函数,我们需要选择一个。如果你都不选了,进到这一个dfs也就没有了意义。
一 ,NC121 字符串的排列
这道题用全排列可以轻松解决。
不过我不想用全排列,我想使用dfs搜索进行解决。
这个是我第一次写的dfs,下面那个dfs完全没有什么意义,因为如果你不选这个节点,你可可以选其他的,for循环会向后执行,而不是你再来一个dfs来决定不选它。
同时上面这个代码还没有进行去重的操作。在一次搜索中搜的是相同的字符,这种情况要去除。
class Solution {
public:
vector<string > vec;
void dfs(string str,vector<int> vis,string s)
{
if(s.size()==str.size())
{
vec.push_back(s);
return ;
}
for(int i=0;i<str.size();i++)
{
if(i!=0)
{
//这一步是为了去除本次搜索过程中搜到相同的字母。使用vis判断
//是为了仅仅去除的是在同一次dfs内的相同的。
if(vis[i-1]==0&&str[i]==str[i-1]) continue;
}
if(vis[i]==0)
{
vis[i]=1;
dfs(str,vis,s+str[i]);
vis[i]=0;
// dfs(str,vis,s);
}
}
return ;
}
vector<string> Permutation(string str) {
if(str=="" ) return vec;
vector<int> vis(str.size()+5);
string s="";
sort(str.begin(),str.end());
dfs(str,vis,s);
return vec;
}
};
二, 加起来和为目标值的组合
class Solution {
public:
vector<vector<int > > vec;
vector<int> v;
int sum;
void dfs(vector<int> num,int target,int index)
{
if(sum>target) return ;
if(sum==target)
{
vec.push_back(v);
return ;
}
for(int i=index;i<num.size();i++)
{
//这一步还是没理解透彻,有这一步是因为,在这一次选择中,之前已经有
//这个数的选或不选了,前面的已经包含后面可能出现的情况了,
//在来一次没有什么意义了。
if(i>index&&num[i]==num[i-1]) continue;
v.push_back(num[i]);
sum+=num[i];
dfs(num,target,i+1);
sum-=num[i];
v.pop_back();
}
}
vector<vector<int> > combinationSum2(vector<int> &num, int target) {
sort(num.begin(), num.end());
dfs(num,target,0);
return vec;
}
};
三,NC27 集合的所有子集
class Solution {
public:
vector< vector<int> > vec;
void dfs(vector<int> s,vector<int> v,int index)
{
vec.push_back(v);
for(int i=index;i<s.size();i++)
{
v.push_back(s[i]);
dfs(s,v,i+1);
v.pop_back();
}
}
vector<vector<int> > subsets(vector<int> &S) {
vector<int> v;
dfs(S,v,0);
return vec;
}
};
四, NC43 没有重复项数字的所有排列
class Solution {
public:
vector<int> v;
vector< vector<int> > vec;
int vis[100000];
void dfs(vector<int> num)
{
if(v.size()==num.size())
{
vec.push_back(v);
return ;
}
for(int i=0;i<num.size();i++)
{
//因为这个题目是没有重复项数字的全排列,所以这一步可以省去
// if(i!=0&&vis[i-1]==0)
// {
// if(num[i]==num[i-1]) continue;
// }
if(vis[i]==0)
{
vis[i]=1;
v.push_back(num[i]);
dfs(num);
vis[i]=0;
v.pop_back();
}
}
}
vector<vector<int> > permute(vector<int> &num) {
sort(num.begin(),num.end());
dfs(num);
return vec;
}
};
五,括号生成
class Solution {
public:
vector< string> vec;
void dfs(string s,int x,int y,int n)
{
if(x>n||y>n||y>x) return ;
if(x==y&&y==n)
{
vec.push_back(s);
return ;
}
dfs(s+'(',x+1,y,n);
dfs(s+')',x,y+1,n);
}
vector<string> generateParenthesis(int n) {
// write code here
dfs("",0,0,n);
return vec;
}
};