创作不易,感谢三连!!
一、N皇后
- class Solution {
- public:
- vector
> ret; - vector
path; - bool checkcol[9];
- bool checkdig1[18];
- bool checkdig2[18];
- int n;
- vector
> solveNQueens(int _n) - {
- n=_n;
- path.resize(n);
- for(int i=0;i
append(n,'.');//先全部初始化成. - dfs(0);
- return ret;
- }
-
- void dfs(int row)
- {
- if(row==n) {ret.push_back(path);return;}
- for(int col=0;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;
- }
- }
- }
- };
二、有效的数独
- class Solution {
- public:
- bool checkrow[9][10];
- bool checkcol[9][10];
- bool checkgrid[3][3][10];
- bool isValidSudoku(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;
- }
- };
三、解数独
- class Solution {
- public:
- bool checkrow[9][10];
- bool checkcol[9][10];
- bool checkgrid[3][3][10];
- void solveSudoku(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
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
- }
- };
四、单词搜索
- class Solution {
- public:
- bool check[6][6];//用来标记选过的位置
- int m,n;
- vector
char>> board; - string word;
- bool exist(vector
char >>& _board, string _word) - {
- board=_board;
- word=_word;
- m=board.size();
- n=board[0].size();
- for(int i=0;i
- for(int j=0;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
=0&&yfalse&&board[x][y]==word[pos]) - {
- check[x][y]=true;
- if(dfs(x,y,pos+1)) return true;
- check[x][y]=false;
- }
- }
- return false;//如果四个方向都找不到,说明确实没有可填的数,直接返回
- }
- };
五、黄金旷工

- class Solution {
- public:
- int ret=0;
- bool check[15][15];
- int m,n;
- int getMaximumGold(vector
int >>& grid) - {
- m=grid.size();
- n=grid[0].size();
- for(int i=0;i
- for(int j=0;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
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
=0&&y - {
- check[x][y]=true;
- dfs(grid,x,y,count+grid[x][y]);
- check[x][y]=false;
- }
- }
- ret=max(count,ret);
- //for循环结束,确实没得填了,更新
- }
- };
六、不同路径III

- class Solution {
- public:
- int ret;
- bool check[20][20];//用来标记
- int m,n,step;//step用来统计可以走的方格个数
- int uniquePathsIII(vector
int >>& grid) - {
- ret=0;
- m=grid.size();
- n=grid[0].size();
- step=0;
- int bx=0,by=0;//记录起点
- //先找起点
- for(int i=0;i
- for(int j=0;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
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
=0&&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类型的返回值来帮助我们判断当前的填法是否正确。比如解数独和单词搜索问题

注:本文转载自blog.csdn.net的✿༺小陈在拼命༻✿的文章"https://blog.csdn.net/weixin_51142926/article/details/137378428"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
评论记录:
回复评论: