dfs专项练习总结

对于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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值