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到头了没,是否找到解决方案了。