DFS:深搜+回溯+剪枝解决矩阵搜索问题

这篇具有很好参考价值的文章主要介绍了DFS:深搜+回溯+剪枝解决矩阵搜索问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

                                               创作不易,感谢三连!! 

一、N皇后

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    vector<vector<string>> ret;
    vector<string> path;
    bool checkcol[9];
    bool checkdig1[18];
    bool checkdig2[18];
    int n;
    vector<vector<string>> solveNQueens(int _n) 
    {
        n=_n;
        path.resize(n);
        for(int i=0;i<n;++i)  path[i].append(n,'.');//先全部初始化成.
         dfs(0);
         return ret;
    }

    void dfs(int row)
    {
        if(row==n) {ret.push_back(path);return;}
        for(int col=0;col<n;++col)//枚举每一行的每个元素
        {
            if(checkcol[col]==false&&checkdig1[n+row-col]==false&&checkdig2[row+col]==false)//n+row-col防止越界
            {
               path[row][col]='Q';
               checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=true;
                dfs(row+1);
                //恢复现场
               path[row][col]='.';
               checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=false;
            }
        }
    }
};

二、有效的数独

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    bool checkrow[9][10];
    bool checkcol[9][10];
    bool checkgrid[3][3][10];
    bool isValidSudoku(vector<vector<char>>& board) 
    {
         for(int row=0;row<9;++row)
         {
            for(int col=0;col<9;++col)
            {
                if(board[row][col]!='.')
                {
                    int num=board[row][col]-'0';
                    if(checkrow[row][num]||checkcol[col][num]||checkgrid[row/3][col/3][num]) return false;
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
                }
            }
         }
         return true;
    }
};

三、解数独

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    bool checkrow[9][10];
    bool checkcol[9][10];
    bool checkgrid[3][3][10];
    void solveSudoku(vector<vector<char>>& board) 
    {
        //初始化
       for(int row=0;row<9;++row)
         for(int col=0;col<9;++col)
         {
            if(board[row][col]!='.')
            {
                int num=board[row][col]-'0';
                checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
            }
         }
        dfs(board);
    }
        bool dfs(vector<vector<char>> &board)//bool用来告诉上一层决策是正确的
         {
           for(int row=0;row<9;++row)
            for(int col=0;col<9;++col)
         {
            if(board[row][col]=='.')
            {
              //开始尝试填数
              for(int num=1;num<=9;++num)
              {
                if(!checkrow[row][num]&&!checkcol[col][num]&&!checkgrid[row/3][col/3][num])
                {
                    //说明能填,就填上
                    board[row][col]=num+'0';
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
                    if(dfs(board)) return true;//去下一个位置填,如果填成功了,返回true
                    //恢复现场
                    board[row][col]='.';
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=false;
                }
              }
              return false;//1-9没有一个数能填,说明决策错误
            }
         }
            return true;//安全地填完了,返回true
         }
};

四、单词搜索

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    bool check[6][6];//用来标记选过的位置
    int m,n;
    vector<vector<char>> board;
    string word;
    bool exist(vector<vector<char>>& _board, string _word) 
    {
        board=_board;
        word=_word;
        m=board.size();
        n=board[0].size();
        for(int i=0;i<m;++i)
         for(int j=0;j<n;++j)
          {
             if(board[i][j]==word[0])
             {
                check[i][j]=true;
                if(dfs(i,j,1))  return true;
                check[i][j]=false;
             }
          }
          return false;
    }
    //用向量的方式来定义
     int dx[4]={0,0,-1,1};
     int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
    bool dfs(int i,int j,int pos)
    {
        if(pos==word.size())  return true;
        for(int k=0;k<4;++k)
        {
           int x=i+dx[k],y=j+dy[k];
           if(x>=0&&x<m&&y>=0&&y<n&&check[x][y]==false&&board[x][y]==word[pos])
           {
               check[x][y]=true;
               if(dfs(x,y,pos+1)) return true;
               check[x][y]=false;
           }
        }
        return false;//如果四个方向都找不到,说明确实没有可填的数,直接返回
    }
};

五、黄金旷工

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    int ret=0;
    bool check[15][15];
    int m,n;
    int getMaximumGold(vector<vector<int>>& grid) 
    {
      m=grid.size();
      n=grid[0].size();
      for(int i=0;i<m;++i)
        for(int j=0;j<n;++j)
          {
            if(grid[i][j])
            {
                check[i][j]=true;
                dfs(grid,i,j,grid[i][j]);
                check[i][j]=false;
            }
          }
          return ret;
     }
      //用向量的方式来定义
     int dx[4]={0,0,-1,1};
     int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
     void dfs(vector<vector<int>>& grid,int i,int j,int count)
     {
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y])
            {
                check[x][y]=true;
                dfs(grid,x,y,count+grid[x][y]);
                check[x][y]=false;
            }
        }
        ret=max(count,ret);
        //for循环结束,确实没得填了,更新
     }
};

六、不同路径III

. - 力扣(LeetCode)

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵

class Solution {
public:
    int ret;
    bool check[20][20];//用来标记
    int m,n,step;//step用来统计可以走的方格个数
    int uniquePathsIII(vector<vector<int>>& grid) 
    {
        ret=0;
        m=grid.size();
        n=grid[0].size();
        step=0;
        int bx=0,by=0;//记录起点
        //先找起点
        for(int i=0;i<m;++i)
          for(int j=0;j<n;++j)
            {
                if(grid[i][j]==0) ++step;
                else if(grid[i][j]==1) 
                {
                    bx=i;
                    by=j;
                }
            }
        step+=2;//把起点和终点算上,最后走到终点的时候就可以返回了
        check[bx][by]=true;
        dfs(grid,bx,by,1);
        return ret;
    }
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
    void dfs(vector<vector<int>>& grid,int i,int j,int count)
    {
        if(grid[i][j]==2&&count==step) {++ret;return;}
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y]!=-1)
            {
                check[i][j]=true;
                dfs(grid,x,y,count+1);
                check[i][j]=false;
            }
        }
    }
};

七、小总结

1、矩阵搜索问题经常要用到向量,也就是我们可以通过dx和dy来帮助我们定义方向

2、矩阵搜索要确保走过的位置不再走过,所以此时有两个策略:

(1)标记数组,比较常用

(2)修改原矩阵的内容,但是这样做的话要我们要确保最后能够把它复原 

3、dfs的返回值不一定是void,如果该题目并不只是完全地去统计,而是涉及到我们做出的选择可能会错误的时候,这个时候我们就需要通过bool类型的返回值来帮助我们判断当前的填法是否正确。比如解数独和单词搜索问题

DFS:深搜+回溯+剪枝解决矩阵搜索问题,递归、搜索与回溯算法总结,深度优先,剪枝,算法,leetcode,c++,矩阵文章来源地址https://www.toymoban.com/news/detail-854913.html

到了这里,关于DFS:深搜+回溯+剪枝解决矩阵搜索问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 专题二:二叉树的深搜【递归、搜索、回溯】

    深度优先遍历 (DFS,全称为DepthFirstTraversal),是我们树或者图这样的数据结构中常用的⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分⽀,直到⼀条路径上的所有节点都被遍历完毕,然后再回溯到上⼀层,继续找⼀条路遍历。 在⼆叉树中,常⻅的深度优先遍历为:

    2024年02月07日
    浏览(41)
  • DFS(基础,回溯,剪枝,记忆化)搜索

    DFS(深度优先搜索) 基于递归求解问题,而针对搜索的过程 对于问题的介入状态叫初始状态,要求的状态叫目标状态 这里的搜索就是对实时产生的状态进行分析检测,直到得到一个目标状态或符合要求的最佳状态为止。对于实时产生新的状态的过程叫扩展 搜索的要点: 1.选定初

    2024年04月12日
    浏览(36)
  • 【算法】回溯:与递归,dfs的同质与分别,剪枝与恢复现场的详细理解,n皇后的回溯解法及算法复杂度分析。

    目录 ​编辑 1.什么是回溯 2.关于剪枝 3.关于恢复现场 4.题目:二叉树的所有路径(凸显恢复现场:切实感受回溯与深搜) 问题分析 ①函数设置为:void Dfs(root) ②函数设置为:void Dfs(root,path) 解题思想:使⽤深度优先遍历(DFS)求解。 代码实现 5.N后问题 问题分析 4皇后的放置

    2024年04月16日
    浏览(41)
  • 穷举&&深搜&&暴搜&&回溯&&剪枝(3)

    一)字母大小写全排列 784. 字母大小写全排列 - 力扣(LeetCode) 1)从每一个字符开始进行枚举,如果枚举的是一个数字字符,直接忽视 如果是字母的话,进行选择是变还是不变 2)当进行遍历到叶子结点的时候,直接将结果存放到ret里面即可 3)相对于是对于这个决策树做一个深度

    2024年02月14日
    浏览(54)
  • 穷举&&深搜&&暴搜&&回溯&&剪枝(4)

    一)单词搜索: 直接在矩阵中依次找到特定字符串 79. 单词搜索 - 力扣(LeetCode) 画出决策树,只需要做一个深度优先遍历: 1)设计dfs函数:只需要关心每一层在做什么即可,从这个节点开始,开始去尝试匹配字符串的下一个字符,就是从某一个位置的字符开始,上下左右下标看看

    2024年02月09日
    浏览(43)
  • 穷举&&深搜&&暴搜&&回溯&&剪枝(2)

    一)电话号码的字母组合 17. 电话号码的字母组合 - 力扣(LeetCode) 1)画出决策树:只是需要对最终的决策树做一个深度优先遍历,在叶子节点收集结果即可 把图画出来,知道每一层在干什么,代码就能写出来了  2)定义全局变量: 1)定义一个哈希表来处理数字和字符串的映射关系

    2024年02月14日
    浏览(44)
  • 【leetcode】深搜、暴搜、回溯、剪枝(C++)3

    leetcode链接 leetcode链接 leetcode链接 leetcode链接

    2024年02月22日
    浏览(36)
  • 【leetcode】深搜、暴搜、回溯、剪枝(C++)2

    leetcode链接 leetcode链接 leetcode链接 全局变量的超时代码: 原因在于nums的长度最长有20,其2^20次方太大了。但是leetcode居然通过了。 path作为参数的正确代码: leetcode链接 解法一: 解法二: 解法一: 解法二: leetcode链接 leetcode链接 leetcode链接 这里我们着重在剪枝方面上面的

    2024年02月20日
    浏览(39)
  • 算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习一(leetcode真题剖析)

    题目链接:https://leetcode.cn/problems/permutations/ 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 示例 2: 示例 3: 提示: 1 = nums.length = 6 -10 = nums[i] = 10 nums 中的所有整数 互不相同 思路 这是一个典型的回溯问题,需要在每

    2024年02月21日
    浏览(70)
  • DFS:二叉树的深搜与回溯

    . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode)  . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) 思路1:全局path+回溯  思路2:形参path记录路径结果 . - 力扣(LeetCode) 思路1:全局path+回溯 思路2:参数path记录路径结果 

    2024年04月16日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包