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;
}
}