LeetCode dfs+回溯合集

17. 电话号码的字母组合

dfs

class Solution {
public:
    vector dict={ 
        "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",
    };
    
    vector letterCombinations(string digits) {
        vectorres;
        if(!digits.size())return res;
        
        string tmp;
        dfs(res,0,tmp,digits);
        
        return res;
    }
    
    void dfs(vector&res,int k,string &tmp,string &digits){
        int n=digits.size();
        if(k>=n){
            res.push_back(tmp);
            return;
        }
        
       string mm=dict[digits[k]-'2'];
        
        for(auto c:mm){
            tmp+=c;
            dfs(res,k+1,tmp,digits);
            tmp.pop_back();
        }
    }
};

bfs

class Solution {
public:
    vector dict={ 
        "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",
    };
    
    vector letterCombinations(string digits) {
        vectorres;
        if(!digits.size())return res;
        
        queueq;
        q.push("");
        
        for(auto c:digits){
            int n=q.size();
            for(int i=0;i

79. 单词搜索

class Solution {
public:
    int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    
    bool exist(vector>& board, string word) {
        int n=board.size(),m=board[0].size();
        vector>vis(n,vector(m));
        
        for(int i=0;i>& board,int t,string &word,vector>&vis){
        if(board[i][j]!=word[t])return false;
        if(t>=word.size()-1) return true;
        
        int n=board.size(),m=board[0].size();
        vis[i][j]=true;
        
        for(int k=0;k<4;k++){
            int a=i+dx[k],b=j+dy[k];
            if(a>=0 && a=0 && b

y总写的,这样就不用多一个vis数组判断是否访问过了%%。
直接把访问过的board[i][j]改为'.',总之就是一个不会合法出现在board数组里的元素

class Solution {
public:
    int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    
    bool exist(vector>& board, string word) {
        int n=board.size(),m=board[0].size();
        
        for(int i=0;i>& board,int t,string &word){
        if(board[i][j]!=word[t])return false;
        if(t>=word.size()-1) return true;
        
        int n=board.size(),m=board[0].size();
        board[i][j]='.';
        
        for(int k=0;k<4;k++){
            int a=i+dx[k],b=j+dy[k];
            if(a>=0 && a=0 && b

46. 全排列

非字典序,代码量较少的写法

class Solution {
public:
    vector> permute(vector& nums) {
        vector> res;
        dfs(res,0,nums);
        
        return res;
    }
    
    void dfs(vector> &res,int k,vector& nums){
        if(k==nums.size()) res.push_back(nums);
        
        for(int i=k;i

字典序写法

class Solution {
public:
    vector> permute(vector& nums) {
        vector> res;
        vectorused(nums.size());
        vectortmp;
        dfs(res,0,nums,tmp,used);
        return res;
    }
    
    void dfs(vector> &res,int k,vector& nums,vector&tmp,vector &used){
        if(k==nums.size()) res.push_back(tmp);
        
        for(int i=0;i

害!辣个蓝人代码量总是比我少一点,我的代码里dfs参数太多了。

class Solution {
public:
    vectorpath;
    vector used;
    
    vector> permute(vector& nums) {
        vector> res;
        int n=nums.size();
        used=vector(n);
        
        dfs(res,0,nums);
        return res;
    }
    
    void dfs(vector> &res,int k,vector& nums){
        if(k==nums.size()) res.push_back(path);
        
        for(int i=0;i

78. 子集

dfs

class Solution {
public:
    vector>res;
    vectortmp;
    int n;

    vector> subsets(vector& nums) {
        n=nums.size();
        dfs(0,nums);
        return res;
    }
    
    void dfs(int k,vector& nums){
        if(k>=n) {
            res.push_back(tmp);
            return;
        }
        tmp.push_back(nums[k]);
        dfs(k+1,nums);
        tmp.pop_back();
        
        dfs(k+1,nums);
    }
};

位运算做法
优点:快
缺点:递归深度不能超过int(32)

class Solution {
public:
    vector>res;
    vectortmp;
    int n;

    vector> subsets(vector& nums) {
        n=nums.size();
        for(int i=0;i<1<tmp;
            for(int j=0;j>j & 1)
                    tmp.push_back(nums[j]);
            }
            res.push_back(tmp);
        }
        return res;
    }
    
};

90. 子集 II

分别用0~k次
第一次for(i=0),用了0次当前数
第二次for(i=1),用了1次当前数
...
第k+1次for(i=k),用了k次当前数

dfs是u+k层的原因:nums[u+k]就是下一个数了

class Solution {
public:
    vector>res;
    vectorpath;

    vector> subsetsWithDup(vector& nums) {
        sort(nums.begin(),nums.end());
        dfs(nums,0);
        return res;
    }
    
    void dfs(vector&nums,int u){
        if(u==nums.size()){
            res.push_back(path);
            return ;
        }
        
//      计算 当前数字的个数
        int k=0;
        while(u+k

216. 组合总和 III

一定要在for枚举选择里添加,和恢复现场

class Solution {
public:
    vector>res;
    vectorpath;

    vector> combinationSum3(int k, int n) {
        dfs(0,0,1,k,n);
        return res;
    }
    
    void dfs(int u,int sum,int cur,int &k,int &n){
        if(u==k){
            if(sum==n)res.push_back(path);
            return ;
        }
        if(sum>n)return ;
        
        for(int i=cur;i<=9;i++){
            sum+=i;
            path.push_back(i);

            dfs(u+1,sum,i+1,k,n);
            
            sum-=i;
            path.pop_back();
        }
    }
};

害!辣个蓝人的代码还是比我简洁。。参数列表里少了usum

class Solution {
public:
    vector>res;
    vectorpath;

    vector> combinationSum3(int k, int n) {
        dfs(1,k,n);
        return res;
    }
    
    void dfs(int cur,int k,int n){
        if(!k){
            if(!n)res.push_back(path);
            return ;
        }
        
        for(int i=cur;i<=9;i++){
            path.push_back(i);
            dfs(i+1,k-1,n-i);
            path.pop_back();
        }
    }
};

52. N皇后 II

这尼玛也太吊了。就这几行

灵魂是:

  1. 从左上到右下的斜线x-y都相等
  2. 从右上到左下的斜线x+y都相等
class Solution {
public:
    int ans=0,n;
    vectorcol,diag,udiag;
    
    int totalNQueens(int _n) {
        n=_n;
        col=vector(n);
        diag=vector(2*n);
        udiag=vector(2*n);
        dfs(0);
        return ans;
    }
    
    void dfs(int u){
        if(u==n){
            ans++;
            return;
        }
//         u是层数,i是列数
        for(int i=0;i

37. 解数独

太吊了,和上面的八皇后一个思路

class Solution {
public:
    bool row[9][9],col[9][9],cell[3][3][9];
    
    void solveSudoku(vector>& board) {
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
                if(board[i][j]!='.'){
                    int t=board[i][j]-'1';
                    row[i][t]=col[j][t]=cell[i/3][j/3][t]=true;
                }
        
        dfs(0,0,board);
    }
    
    bool dfs(int x,int y,vector>& board){
        if(y==9)x++,y=0;
        if(x==9)return true;
//         相当于剪枝
        if(board[x][y]!='.')return dfs(x,y+1,board);
        
        for(int i=0;i<9;i++){
            if(!row[x][i] && !col[y][i] && !cell[x/3][y/3][i]){
                row[x][i]=col[y][i]=cell[x/3][y/3][i]=true;
                board[x][y]=i+'1';
                
                if(dfs(x,y,board))return true;
                row[x][i]=col[y][i]=cell[x/3][y/3][i]=false;
                board[x][y]='.';
            }
        }
        return false;
    }
};

473. 火柴拼正方形

之前好像是自己写的吧。。害挺聪明

class Solution {
  public:
    vector vis;
    bool dfs(vector &nums, int i, int target, int cur_sum) {
        if (cur_sum == target) return true;
        for (int j = i; j < nums.size(); j++) {
            if (!vis[j] && nums[j] + cur_sum <= target) {
                vis[j] = true;
                if (dfs(nums, j, target, cur_sum + nums[j])) return true;
                vis[j] = false;
            }
        }
        return false;
    }
    bool makesquare(vector &nums) {
        if (nums.size() < 4) return false;
        // 从大到小排序
        sort(nums.rbegin(), nums.rend());
        vis = vector(nums.size(), false);
        int sum = 0, target;
        for (int num : nums) sum += num;
        if (sum % 4) return false;
        target = sum / 4;
        
        int i=0;
        for (int j = 0; j < 4; j++) {
            while (vis[i]) i++;
            if (!dfs(nums, i, target, 0)) return false;
        }
        return true;
    }
};

这么多剪枝记不太住啊


class Solution {
public:
    vectorused;
    
    bool makesquare(vector& nums) {
        int sum=0;
        for(auto i :nums)sum+=i;
        if(!sum || sum%4)return false;
        
        used=vector(nums.size());
        sort(nums.rbegin(),nums.rend());
        
        return dfs(nums,0,0,sum/4);
    }
    
    bool dfs(vector&nums,int u,int cur,int length){
        if(cur==length)u++,cur=0;
        if(u==4)return true;
        
        for(int i=0;i

你可能感兴趣的:(LeetCode dfs+回溯合集)