Sudoku
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfyall 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'.'
.
Example
Example 1:
Copy Input:
[
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
Output:
true
Example 2:
Copy Input:
[
["8","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
Output:
false
Explanation:
Same as Example 1, except with the 5 in the top left corner being modified to 8.
Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Note:
The given board contain only digits1-9
and the character'.'
.
You may assume that the given Sudoku puzzle will have a single unique solution.
The given board size is always9x9
Note
Judge is Valid - set version: Time O(9*9) space O(3*9)
Copy board[3*(i/3) + j/3][3*(i%3) + j%3]
i是0的时候,判断第一个九宫格,依次类推
Copy public boolean isValidSudoku( char [][] board) {
for ( int i = 0 ; i < 9 ; i ++ ) {
HashSet < Character > rows = new HashSet <>();
HashSet < Character > cols = new HashSet <>();
HashSet < Character > cell = new HashSet <>();
for ( int j = 0 ; j < 9 ; j ++ ) {
if (board[i][j] != '.' && ! rows . add (board[i][j])) return false ;
if (board[j][i] != '.' && ! cols . add (board[j][i])) return false ;
if (board[ 3 * (i / 3 ) + j / 3 ][ 3 * (i % 3 ) + j % 3 ] != '.'
&& ! cell . add (board[ 3 * (i / 3 ) + j / 3 ][ 3 * (i % 3 ) + j % 3 ]))
return false ;
}
}
return true ;
}
Judge is Valid - trick version 不推荐:
Copy public boolean isValidSudoku( char [][] board) {
for ( int i = 0 ; i < 9 ; i ++ ) {
for ( int j = 0 ; j < 9 ; j ++ ) {
if (board[i][j] == '.' ) continue ;
if ( ! isValid(board , i , j) ) return false ;
}
}
return true ;
}
private static boolean isValid( char [][] board , int i , int j) {
for ( int row = 0 ; row < 9 ; row ++ ) {
if (row == i) continue ;
if (board[row][j] == board[i][j]) return false ;
}
for ( int col = 0 ; col < 9 ; col ++ ) {
if (col == j) continue ;
if (board[i][col] == board[i][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) continue ;
if (board[i][j] == board[row][col]) return false ;
}
}
return true ;
}
Solver:
暴力去添加1到9,如果合适(valid)就继续dfs,search函数是boolean,不行就改回去,都不行这一层就是false
Code
Copy class Solution {
public void solveSudoku ( char [][] board) {
if (board == null || board . length == 0 ) return ;
solve(board) ;
}
private static 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 ++ ) {
if ( isValid(board , i , j , c) ) {
board[i][j] = c;
if ( solve(board) ) return true ;
else board[i][j] = '.' ;
}
}
return false ;
}
}
}
return true ;
}
private static boolean isValid ( char [][] board , int row , int col , char c) {
for ( int i = 0 ; i < board . length ; i ++ ) {
if (board[i][col] != '.' && board[i][col] == c) return false ;
if (board[row][i] != '.' && board[row][i] == c) return false ;
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 ;
}
return true ;
}
}