Hard!
题目描述:
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字
1-9
和字符'.'
。 - 你可以假设给定的数独只有唯一解。
- 给定数独永远是
9x9
形式的。
解题思路:
这道求解数独的题是在之前那道 Valid Sudoku 验证数独的基础上的延伸,之前那道题让我们验证给定的数组是否为数独数组,这道让我们求解数独数组。
对于每个需要填数字的格子带入1到9,每代入一个数字都判定其是否合法,如果合法就继续下一次递归。
结束时把数字设回'.',判断新加入的数字是否合法时,只需要判定当前数字是否合法,不需要判定这个数组是否为数独数组,因为之前加进的数字都是合法的,这样可以使程序更加高效一些。
C++解法一:
1 class Solution { 2 public: 3 void solveSudoku(vector<vector<char> > &board) { 4 if (board.empty() || board.size() != 9 || board[0].size() != 9) return; 5 solveSudokuDFS(board, 0, 0); 6 } 7 bool solveSudokuDFS(vector<vector<char> > &board, int i, int j) { 8 if (i == 9) return true; 9 if (j >= 9) return solveSudokuDFS(board, i + 1, 0); 10 if (board[i][j] == '.') { 11 for (int k = 1; k <= 9; ++k) { 12 board[i][j] = (char)(k + '0'); 13 if (isValid(board, i , j)) { 14 if (solveSudokuDFS(board, i, j + 1)) return true; 15 } 16 board[i][j] = '.'; 17 } 18 } else { 19 return solveSudokuDFS(board, i, j + 1); 20 } 21 return false; 22 } 23 bool isValid(vector<vector<char> > &board, int i, int j) { 24 for (int col = 0; col < 9; ++col) { 25 if (col != j && board[i][j] == board[i][col]) return false; 26 } 27 for (int row = 0; row < 9; ++row) { 28 if (row != i && board[i][j] == board[row][j]) return false; 29 } 30 for (int row = i / 3 * 3; row < i / 3 * 3 + 3; ++row) { 31 for (int col = j / 3 * 3; col < j / 3 * 3 + 3; ++col) { 32 if ((row != i || col != j) && board[i][j] == board[row][col]) return false; 33 } 34 } 35 return true; 36 } 37 };