[LeetCode] 37. Sudoku Solver 求解数独
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
- Each of the digits
1-9
must occur exactly once in each row. - Each of the digits
1-9
must occur exactly once in each column. - Each of the the digits
1-9
must occur exactly once in each of the 93x3
sub-boxes of the grid.
Empty cells are indicated by the character '.'
.
A sudoku puzzle...
...and its solution numbers marked in red.
Note:
- The given board contain only digits
1-9
and the character'.'
. - You may assume that the given Sudoku puzzle will have a single unique solution.
- The given board size is always
9x9
.
36. Valid Sudoku 拓展,36题让验证是否为数独数组,这道求解数独数组,跟此题类似的有 Permutations 全排列,Combinations 组合项, N-Queens N皇后问题等,其中尤其是跟 N-Queens N皇后问题的解题思路及其相似,对于每个需要填数字的格子带入1到9,每代入一个数字都判定其是否合法,如果合法就继续下一次递归,结束时把数字设回'.',判断新加入的数字是否合法时,只需要判定当前数字是否合法,不需要判定这个数组是否为数独数组,因为之前加进的数字都是合法的,可以使程序更高效。
解法:backtracking
Java:
public class Solution { public void solveSudoku(char[][] board) { if(board == null || board.length == 0) return; solve(board); } public boolean solve(char[][] board){ for(int i = 0; i < board.length; i++){ for(int j = 0; j < board[0].length; j++){ if(board[i][j] == '.'){ for(char c = '1'; c <= '9'; c++){//trial. Try 1 through 9 if(isValid(board, i, j, c)){ board[i][j] = c; //Put c for this cell if(solve(board)) return true; //If it's the solution return true else board[i][j] = '.'; //Otherwise go back } } return false; } } } return true; } private boolean isValid(char[][] board, int row, int col, char c){ for(int i = 0; i < 9; i++) { if(board[i][col] != '.' && board[i][col] == c) return false; //check row if(board[row][i] != '.' && board[row][i] == c) return false; //check column if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' && board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block } return true; } }
Python:
class Solution: # @param board, a 9x9 2D array # Solve the Sudoku by modifying the input board in-place. # Do not return any value. def solveSudoku(self, board): def isValid(board, x, y): for i in xrange(9): if i != x and board[i][y] == board[x][y]: return False for j in xrange(9): if j != y and board[x][j] == board[x][y]: return False i = 3 * (x / 3) while i < 3 * (x / 3 + 1): j = 3 * (y / 3) while j < 3 * (y / 3 + 1): if (i != x or j != y) and board[i][j] == board[x][y]: return False j += 1 i += 1 return True def solver(board): for i in xrange(len(board)): for j in xrange(len(board[0])): if(board[i][j] == '.'): for k in xrange(9): board[i][j] = chr(ord('1') + k) if isValid(board, i, j) and solver(board): return True board[i][j] = '.' return False return True
C++:
class Solution { public: void solveSudoku(vector<vector<char> > &board) { if (board.empty() || board.size() != 9 || board[0].size() != 9) return; solveSudokuDFS(board, 0, 0); } bool solveSudokuDFS(vector<vector<char> > &board, int i, int j) { if (i == 9) return true; if (j >= 9) return solveSudokuDFS(board, i + 1, 0); if (board[i][j] == '.') { for (int k = 1; k <= 9; ++k) { board[i][j] = (char)(k + '0'); if (isValid(board, i , j)) { if (solveSudokuDFS(board, i, j + 1)) return true; } board[i][j] = '.'; } } else { return solveSudokuDFS(board, i, j + 1); } return false; } bool isValid(vector<vector<char> > &board, int i, int j) { for (int col = 0; col < 9; ++col) { if (col != j && board[i][j] == board[i][col]) return false; } for (int row = 0; row < 9; ++row) { if (row != i && board[i][j] == board[row][j]) return false; } for (int row = i / 3 * 3; row < i / 3 * 3 + 3; ++row) { for (int col = j / 3 * 3; col < j / 3 * 3 + 3; ++col) { if ((row != i || col != j) && board[i][j] == board[row][col]) return false; } } return true; } };
类似题目:
[LeetCode] 36. Valid Sudoku 验证数独
All LeetCode Questions List 题目汇总