首页 > 代码库 > Leetcode | Valid Sudoku & Sudoku Solver

Leetcode | Valid Sudoku & Sudoku Solver

判断valid,没有更好的方法,只能brute force。

 1 class Solution {
 2 public:
 3     bool isValidSudoku(vector<vector<char> > &board) {
 4         
 5         int n;
 6         for (int i = 0; i < 9; ++i) {
 7             vector<bool> contained(9, false);
 8             for (int j = 0; j < 9; ++j) {
 9                 if (board[i][j] == .) continue;
10                 n = board[i][j] - 0 - 1;
11                 if (contained[n]) return false;
12                 contained[n] = true;
13             }
14         }
15         
16         for (int i = 0; i < 9; ++i) {
17             vector<bool> contained(9, false);
18             for (int j = 0; j < 9; ++j) {
19                 if (board[j][i] == .) continue;
20                 n = board[j][i] - 0 - 1;
21                 if (contained[n]) return false;
22                 contained[n] = true;
23             }
24         }
25         
26         for (int i = 0; i < 3; ++i) {
27             for (int j = 0; j < 3; ++j) {
28                 vector<bool> contained(9, false);
29                 for (int k = 0; k < 3; ++k) {
30                     for (int m = 0; m < 3; ++m) {
31                         if (board[i*3+k][j*3+m] == .) continue;
32                         n = board[i*3+k][j*3+m] - 0 - 1;
33                         if (contained[n]) return false;
34                         contained[n] = true;
35                     }
36                 }
37             }
38         }
39         return true;
40     }
41 };

求解决方案也只有backtrack。

 1 class Solution {
 2 public:
 3     void solveSudoku(vector<vector<char> > &board) {
 4         list<int> unsolved;
 5         getUnsolved(board, unsolved);
 6         recursive(board, unsolved);
 7     }
 8     
 9     bool recursive(vector<vector<char> > &board, list<int> &unsolved) {
10         if (unsolved.empty()) return true;
11         int loc = unsolved.front();
12         int row = loc / 9;
13         int col = loc % 9;
14         
15         vector<bool> contained(9, false);
16         int n;
17         for (int i = 0; i < 9; ++i) {
18             if (board[row][i] != .) {
19                 contained[board[row][i] - 0 - 1] = true;
20             }
21             if (board[i][col] != .) {
22                 contained[board[i][col] - 0 - 1] = true;
23             }
24         }
25         
26         row = row / 3; col = col / 3;
27         for (int i = 0; i < 3; ++i) {
28             for (int j = 0; j < 3; ++j) {
29                 if (board[row * 3 + i][col * 3 + j] != .) {
30                     contained[board[row * 3 + i][col * 3 + j] - 0 - 1] = true;
31                 }
32             }
33         }
34         
35         row = loc / 9; col = loc % 9;
36         for (int i = 0; i < 9; ++i) {
37             if (!contained[i]) {
38                 board[row][col] = i + 1 + 0; 
39                 unsolved.pop_front();
40                 if (recursive(board, unsolved)) return true;
41                 board[row][col] = .;
42                 unsolved.push_front(loc);
43             }
44         }
45         
46         return false;
47     }
48     
49     void getUnsolved(vector<vector<char> > &board, list<int> &unsolved) {
50         for (int i = 0; i < 9; i++) {
51             for (int j = 0; j < 9; ++j) {
52                 if (board[i][j] == .) {
53                     unsolved.push_back(i * 9 + j);
54                 }
55             }
56         }
57     }
58 };

用unsolved数组可以避免每次都需要从头扫到尾去找下一个元素。

用contained数组先保存了在该行该格该九宫格里已经存在的数字。这样就可以直接去试验剩下的数字,而不需要每次都再检查一遍插入的值是否合法。

backtrack是一个要有返回值,否则都不知道你backtrack到头了没,是否找到解决方案了。