这种细节满满的hard题还是很累人的,主要是穷举+dfs+剪枝,有一个地方让我卡了挺久的,在当前层遍历的时候,如果碰到了已经填好的数字,应该是dfs当前行下一列!!然后再continue。
递归边界就是到了越界的那一行n就证明找到解了,不然到不了这里,如果当列到了9,就去下一行。
最难的就是九宫格判断是否有重复的,一定要多思考思考
class Solution {
public:
bool isValid(int r,int c,char n,vector<vector<char>>& board){
//判断行列九宫格是否有相同的
for (int i = 0; i < 9; i++) {
// 判断行是否存在重复
if (board[r][i] == n) return false;
// 判断列是否存在重复
if (board[i][c] == n) return false;
// 判断 3 x 3 方框是否存在重复
if (board[(r/3)*3 + i/3][(c/3)*3 + i%3] == n)
return false;
}
return true;
}
bool dfs(vector<vector<char>>& board,int row, int col){
if(col == 9){
return dfs(board,row+1,0);
}
//如果行越界了直接true
if(row == 9){
return true;
}
for(int i = row; i < board.size(); ++i){
for(int j = col; j < board[0].size(); ++j){
if(board[i][j] != '.'){
return dfs(board,i,j+1);
continue;
}
for(int k = 1; k <= 9; ++k){
//先判断填入当前数字后是否合法
//如果合法再将其改了,然后接下去判断
char ch = k + '0';
if(!isValid(i,j,ch,board))
continue;
board[i][j] = ch;
if(dfs(board,i,j+1)) return true;
board[i][j] = '.';
}
// 穷举完 1~9,依然没有找到可行解,此路不通
return false;
}
}
return false;
}
void solveSudoku(vector<vector<char>>& board) {
//如果是判断是否有效只需要用哈希,如果是填数独的话
//对每个空格子穷举所有情况,如果不对了就回溯
//一定有可行解,尽情dfs即可,如果填入的当前数字,使得数独不合理,写一个函数判断。就continue,dfs是bool的,有一个可行解就true。如果当前dfs下去的结果不行,记得将当前数字改回.,然后return false
dfs(board,0,0);
}
};