算法整理-回溯和DFS

Posted cookcoder-mr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法整理-回溯和DFS相关的知识,希望对你有一定的参考价值。

一.  八皇后问题

     第一种解法将棋盘的所有格子都初始化为‘.’,  定义递归函数为前l-1行的格子已经排好(给定排面的情况下), 从第l层开始继续排得到的八皇后搜索结果。具体做法是从第l行的每一个列逐列尝试,如果不冲突则加入,再进行l+1的问题求解,求解完后进行回溯。空间复杂度为O(N*N)

class Solution 
public:
    int totalNQueens(int n) 
        vector<vector<int>> round(n, vector<int>(n, 0));
        int total = 0;
        btsearch(round, 0, n, total);
        return total;
    

private:
    void btsearch(vector<vector<int>> &round, int t, int n, int &total) 
       if (t == n) 
           total++;
           return;
           
       for (int i = 0; i < n; i++) 
            
            if (isok(round, t, i)) 
                round[t][i] = 1;
                btsearch(round, t+1, n, total);
                round[t][i] = 0;
            
           
       
    

    bool isok(const vector<vector<int>>round, int t, int j) 
       int n = round.size();
       for (int c=0; c<t; c++) 
           if (round[c][j] == 1) return false;
       
       for (int r=0; r<j; r++) 
           if (round[t][r] == 1) return false;
       

       // 45 o
       for (int c=t-1, r=j+1; c>=0 && r<n; c--, r++) 
           if (round[c][r] == 1) return false;
       
      // 135 o
       for (int c=t-1, r=j-1; c>=0 && r>=0; c--, r-- ) 
           if (round[c][r] == 1) return false;
       
     //  nqueque = 4。
     return true;
    
;

 

class Solution 
public:
    int totalNQueens(int n) 
        vector<vector<int>> round(n, vector<int>(n, 0));
        int total = 0;
        btsearch(round, 0, n, total);
        return total;
    

private:
    void btsearch(vector<vector<int>> &round, int t, int n, int &total) 
       if (t == n) 
           total++;
           return;
           
       for (int i = 0; i < n; i++) 
            
            if (isok(round, t, i)) 
                round[t][i] = 1;
                btsearch(round, t+1, n, total);
                round[t][i] = 0;
            
           
       
    

    bool isok(const vector<vector<int>>round, int t, int j) 
       int n = round.size();
       for (int c=0; c<t; c++) 
           if (round[c][j] == 1) return false;
       
       for (int r=0; r<j; r++) 
           if (round[t][r] == 1) return false;
       

 

 

 第二种方法类似,不过可以将格子表示成一个一维数组,第i个元素的值j表示将皇后放在第i行第j列

 

二. Permutation

 对一个数组进行全排列,无重复元素,定义递归函数为前i-1个元素全排列已经排好, 将第i个元素以及后面的元素进行全排列。过程为从第i个元素到最后一个元素轮流放在第i个位置上, 然后对第i+1个元素以及后续元素进行全排列。

class Solution 
public:
    vector<vector<int>> permute(vector<int>& nums) 
        vector<vector<int>> res;
        permutehelper(nums, 0, res);
        return res;
    

private:
    void permutehelper(vector<int>&nums, int l, vector<vector<int>> &res)
        if (l == nums.size()) 
            res.push_back(nums);       
       for (int i = l; i < nums.size(); i++) 
                swap(nums[l], nums[i]);
                permutehelper(nums, l+1, res);
                swap(nums[i], nums[l]);
            
   
      

;

   若有重复,则先进行sort, 并且轮流当头那部分相同的数字只能出现一次,

class Solution 
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) 
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        helper(nums, 0, res);
        return res;
    

private:
    void helper(vector<int>& nums, int l, vector<vector<int>> &res) 
        if (l == nums.size()) res.push_back(nums);
        set<int> vis;
        for (int i=l; i< nums.size(); i++) 
                if (vis.count(nums[i])) continue;
                vis.insert(nums[i]);
                swap(nums[l], nums[i]);
                helper(nums, l+1, res);
                swap(nums[i], nums[l]);
        
    
;

 

三. 整数拆分

 

 

四. CombineSum

 

class Solution 
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
        vector<vector<int>> res;
        vector<int> out;
        btsearch(candidates, 0, target, out, res);
        return res;
    

    void btsearch(vector<int> candidates,  int l, int target,  vector<int> &out, vector<vector<int>>&res) 
       if (target < 0) 
            return;
        
       if (target == 0) 
           res.push_back(out);
           return;
       
       for (int i = l ; i< candidates.size(); i++) 
           out.push_back(candidates[i]);
           btsearch(candidates, i, target - candidates[i], out, res);
           out.pop_back();
       

    
;

 

五. CombineSumII

class Solution 
public:
    vector<vector<int> > combinationSum2(vector<int> &num, int target) 
        vector<vector<int> > res;
        vector<int> out;
        sort(num.begin(), num.end());
        combinationSum2DFS(num, target, 0, out, res);
        return res;
    
    void combinationSum2DFS(vector<int> &num, int target, int start, vector<int> &out, vector<vector<int> > &res) 
        if (target < 0) return;
        else if (target == 0) res.push_back(out);
        else 
            for (int i = start; i < num.size(); ++i) 
                if (i > start && num[i] == num[i - 1]) continue;
                out.push_back(num[i]);
                combinationSum2DFS(num, target - num[i], i + 1, out, res);
                out.pop_back();
            
        
    
;

 

六. subsets

https://www.cnblogs.com/TenosDoIt/p/3451902.html

每一个元素有选择放或者不放两种选择。

class Solution 
public:
    vector<vector<int>> subsets(vector<int>& nums) 
        vector<vector<int>> res;
        vector<int> out;
        helper(nums, 0, out, res);
        return res;
    

private:
    void helper(vector<int>nums, int l, vector<int>&out, vector<vector<int>>&res) 
        if (l == nums.size()) 
            res.push_back(out);
            return;
        
        out.push_back(nums[l]);
        helper(nums, l+1, out, res);
        out.pop_back();
        helper(nums, l+1, out, res);
    
;

 

以上是关于算法整理-回溯和DFS的主要内容,如果未能解决你的问题,请参考以下文章

算法设计与分析知识点整理

算法设计与分析知识点整理

算法设计与分析知识点整理

回溯 DFS 深度优先搜索[待更新]

回溯算法

算法知识目录整理