首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

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

  • 25-03-02 23:02
  • 3816
  • 6646
blog.csdn.net

                                               创作不易,感谢三连!! 

一、N皇后

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. vector> ret;
  4. vector path;
  5. bool checkcol[9];
  6. bool checkdig1[18];
  7. bool checkdig2[18];
  8. int n;
  9. vector> solveNQueens(int _n)
  10. {
  11. n=_n;
  12. path.resize(n);
  13. for(int i=0;iappend(n,'.');//先全部初始化成.
  14. dfs(0);
  15. return ret;
  16. }
  17. void dfs(int row)
  18. {
  19. if(row==n) {ret.push_back(path);return;}
  20. for(int col=0;col//枚举每一行的每个元素
  21. {
  22. if(checkcol[col]==false&&checkdig1[n+row-col]==false&&checkdig2[row+col]==false)//n+row-col防止越界
  23. {
  24. path[row][col]='Q';
  25. checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=true;
  26. dfs(row+1);
  27. //恢复现场
  28. path[row][col]='.';
  29. checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=false;
  30. }
  31. }
  32. }
  33. };

二、有效的数独

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. bool checkrow[9][10];
  4. bool checkcol[9][10];
  5. bool checkgrid[3][3][10];
  6. bool isValidSudoku(vectorchar>>& board)
  7. {
  8. for(int row=0;row<9;++row)
  9. {
  10. for(int col=0;col<9;++col)
  11. {
  12. if(board[row][col]!='.')
  13. {
  14. int num=board[row][col]-'0';
  15. if(checkrow[row][num]||checkcol[col][num]||checkgrid[row/3][col/3][num]) return false;
  16. checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
  17. }
  18. }
  19. }
  20. return true;
  21. }
  22. };

三、解数独

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. bool checkrow[9][10];
  4. bool checkcol[9][10];
  5. bool checkgrid[3][3][10];
  6. void solveSudoku(vectorchar>>& board)
  7. {
  8. //初始化
  9. for(int row=0;row<9;++row)
  10. for(int col=0;col<9;++col)
  11. {
  12. if(board[row][col]!='.')
  13. {
  14. int num=board[row][col]-'0';
  15. checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
  16. }
  17. }
  18. dfs(board);
  19. }
  20. bool dfs(vectorchar>> &board)//bool用来告诉上一层决策是正确的
  21. {
  22. for(int row=0;row<9;++row)
  23. for(int col=0;col<9;++col)
  24. {
  25. if(board[row][col]=='.')
  26. {
  27. //开始尝试填数
  28. for(int num=1;num<=9;++num)
  29. {
  30. if(!checkrow[row][num]&&!checkcol[col][num]&&!checkgrid[row/3][col/3][num])
  31. {
  32. //说明能填,就填上
  33. board[row][col]=num+'0';
  34. checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
  35. if(dfs(board)) return true;//去下一个位置填,如果填成功了,返回true
  36. //恢复现场
  37. board[row][col]='.';
  38. checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=false;
  39. }
  40. }
  41. return false;//1-9没有一个数能填,说明决策错误
  42. }
  43. }
  44. return true;//安全地填完了,返回true
  45. }
  46. };

四、单词搜索

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. bool check[6][6];//用来标记选过的位置
  4. int m,n;
  5. vectorchar>> board;
  6. string word;
  7. bool exist(vectorchar>>& _board, string _word)
  8. {
  9. board=_board;
  10. word=_word;
  11. m=board.size();
  12. n=board[0].size();
  13. for(int i=0;i
  14. for(int j=0;j
  15. {
  16. if(board[i][j]==word[0])
  17. {
  18. check[i][j]=true;
  19. if(dfs(i,j,1)) return true;
  20. check[i][j]=false;
  21. }
  22. }
  23. return false;
  24. }
  25. //用向量的方式来定义
  26. int dx[4]={0,0,-1,1};
  27. int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
  28. bool dfs(int i,int j,int pos)
  29. {
  30. if(pos==word.size()) return true;
  31. for(int k=0;k<4;++k)
  32. {
  33. int x=i+dx[k],y=j+dy[k];
  34. if(x>=0&&x=0&&yfalse&&board[x][y]==word[pos])
  35. {
  36. check[x][y]=true;
  37. if(dfs(x,y,pos+1)) return true;
  38. check[x][y]=false;
  39. }
  40. }
  41. return false;//如果四个方向都找不到,说明确实没有可填的数,直接返回
  42. }
  43. };

五、黄金旷工

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. int ret=0;
  4. bool check[15][15];
  5. int m,n;
  6. int getMaximumGold(vectorint>>& grid)
  7. {
  8. m=grid.size();
  9. n=grid[0].size();
  10. for(int i=0;i
  11. for(int j=0;j
  12. {
  13. if(grid[i][j])
  14. {
  15. check[i][j]=true;
  16. dfs(grid,i,j,grid[i][j]);
  17. check[i][j]=false;
  18. }
  19. }
  20. return ret;
  21. }
  22. //用向量的方式来定义
  23. int dx[4]={0,0,-1,1};
  24. int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
  25. void dfs(vectorint>>& grid,int i,int j,int count)
  26. {
  27. for(int k=0;k<4;++k)
  28. {
  29. int x=i+dx[k],y=j+dy[k];
  30. if(x>=0&&x=0&&y
  31. {
  32. check[x][y]=true;
  33. dfs(grid,x,y,count+grid[x][y]);
  34. check[x][y]=false;
  35. }
  36. }
  37. ret=max(count,ret);
  38. //for循环结束,确实没得填了,更新
  39. }
  40. };

六、不同路径III

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. int ret;
  4. bool check[20][20];//用来标记
  5. int m,n,step;//step用来统计可以走的方格个数
  6. int uniquePathsIII(vectorint>>& grid)
  7. {
  8. ret=0;
  9. m=grid.size();
  10. n=grid[0].size();
  11. step=0;
  12. int bx=0,by=0;//记录起点
  13. //先找起点
  14. for(int i=0;i
  15. for(int j=0;j
  16. {
  17. if(grid[i][j]==0) ++step;
  18. else if(grid[i][j]==1)
  19. {
  20. bx=i;
  21. by=j;
  22. }
  23. }
  24. step+=2;//把起点和终点算上,最后走到终点的时候就可以返回了
  25. check[bx][by]=true;
  26. dfs(grid,bx,by,1);
  27. return ret;
  28. }
  29. int dx[4]={0,0,-1,1};
  30. int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
  31. void dfs(vectorint>>& grid,int i,int j,int count)
  32. {
  33. if(grid[i][j]==2&&count==step) {++ret;return;}
  34. for(int k=0;k<4;++k)
  35. {
  36. int x=i+dx[k],y=j+dy[k];
  37. if(x>=0&&x=0&&y-1)
  38. {
  39. check[i][j]=true;
  40. dfs(grid,x,y,count+1);
  41. check[i][j]=false;
  42. }
  43. }
  44. }
  45. };

七、小总结

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

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

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

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

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

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览59972 人正在系统学习中
注:本文转载自blog.csdn.net的✿༺小陈在拼命༻✿的文章"https://blog.csdn.net/weixin_51142926/article/details/137378428"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

137
数学
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top