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
.
- The given board contain only digits
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 题目汇总