LeetCode-Sudoku Solver

https://leetcode-cn.com/problems/sudoku-solver/

首先,采用非常暴力的递归回溯,并使用了 Valid Sudoku 中对数独中数字进行验证的方法。需要注意返回 true 和 false 的时机。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func solveSudoku(board [][]byte)  {
solve(&board)
}
func solve(board *[][]byte) bool{
for i:=0;i<9;i++ {
for j:=0;j<9;j++ {
if (*board)[i][j]=='.' {
var k byte
for k='1';k<='9';k++ {
if isValid(board,i,j,k) {
(*board)[i][j]=k
if solve(board) {
return true
}else{
(*board)[i][j]='.'
}
}
}
return false
}
}
}
return true
}
func isValid(board *[][]byte, row,col int, val byte) bool {
for i:=0;i<9;i++ {
if (*board)[i][col]==val || (*board)[row][i]==val || (*board)[(row/3)*3+i/3][(col/3)*3+i%3]==val {
return false
}
}
return true
}

下面是一个毫无新意的C++版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public:
bool isValid(vector<vector<char>>& board, int m, int n, char k) {
for(int i=0; i<9; ++i) {
if(k == board[m][i] || k == board[i][n] || k == board[m/3*3+i/3][n/3*3+i%3]) {
return false;
}
}
return true;
}
bool solve(vector<vector<char>>& board) {
for(int i=0; i<9; ++i) {
for(int j=0; j<9; ++j) {
if(board[i][j] == '.') {
for(int k='1'; k<='9'; ++k) {
if(isValid(board, i, j, k)) {
board[i][j] = k;
if(solve(board)) return true;
else board[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
solve(board);
}
};

在 Discuss 中还有一种更牛的 Solution,他通过自己为 Sudoku 中的每一个格子建立一个 cell 结构体来存储可能的信息,然后再通过按可能填入数字的多少进行排序,以减少 backtrack 的次数。