题解
https://www.acwing.com/solution/content/8689/
地址
https://leetcode-cn.com/problems/sudoku-solver/submissions/
描述
思想
枚举每个点,如果是空格,就选择合适的点进行填数,然后不断往下搜索,直到填完所有数(x == n)时,dfs从里不断返回true,直到退到最外面的递归函数位置
这里bool型dfs的好处是可以防止找到一种方案了,还去恢复现场
注意:这里不同于n皇后问题,这里是修改原数组(修改成一种可行解即可),而皇后问题是输出结果,不是修改原数组
代码
class Solution {
public:
// row[x][u]表示第x行是否已经填过数字u(0-8)
// col[y][u]表示第y行是否已经填过数字u(0-8)
// box[x / 3][y / 3][u]表示第[x/3,y/3]个box是否已经填过数字u(0-8)
bool row[9][9],col[9][9],box[3][3][9];
void solveSudoku(vector<vector<char>>& b) {
//首先进行初始化
memset(row,0,sizeof row);
memset(col,0,sizeof col);
memset(box,0,sizeof box);
//将板子中已经填入的数记录下来
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(b[i][j]!='.'){
int t=b[i][j]-'1';
row[i][t]=col[j][t]=box[i/3][j/3][t]=true;
}
}
}
dfs(b,0,0);
}
bool dfs(vector<vector<char>> &b,int x,int y){
if(y==9) x++,y=0;
//所有的格子都填完了
if(x==9) return true;
//这个格子已经填好了,跳过
if(b[x][y]!='.') return dfs(b,x,y+1);
//从1~9中选择该放进哪个数
for(int i=0;i<9;i++){
//这个数在行列还有3*3宫格中都没出现过
if(!row[x][i]&&!col[y][i]&&!box[x/3][y/3][i]){
b[x][y]=i+'1';
row[x][i]=col[y][i]=box[x/3][y/3][i]=true;
// 如果下面搜索后是对的,就提前返回,不恢复现场(因为要修改board);
// 如果是false就恢复现场(这个方法很巧妙)
if(dfs(b,x,y+1)) return true;
//回溯
b[x][y]='.';
row[x][i] = col[y][i] = box[x / 3][y / 3][i] = false;
}
}
//9个数都试过了还不行,就return false;
return false;
}
};