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 digits
1-9
must occur exactly once in each of the 93x3
sub-boxes of the grid.
The '.'
character indicates empty cells.
Example 1:
Input: board = [["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: [["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] Explanation: The input board is shown above and the only valid solution is shown below:
Constraints:
board.length == 9
board[i].length == 9
board[i][j]
is a digit or'.'
.- It is guaranteed that the input board has only one solution.
方案
Runtime: 0 ms, faster than 100.00% of Go online submissions for Sudoku Solver.
Memory Usage: 2.2 MB, less than 42.86% of Go online submissions for Sudoku Solver.
1. 找到所有空格,并计算每个空格可填的答案,保存为列表
2. 回溯填入可填写的答案
循环填入第一步可填写的答案
如果填入可以填入,
填入,并填入下一个,如果也正常,任务答案正确
如果不正确重置当前空格为空
上代码:
type Grid struct {
x int
y int
allowds []byte
}
func solveSudoku(board [][]byte) {
var gridlist []Grid
// check rows
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
if board[i][j] == 46 { // 46 is .
allowds := getAllows(board, i, j)
gridlist = append(gridlist, Grid{x:i, y:j, allowds:allowds})
}
}
}
if len(gridlist) > 0 {
setGrid(board, gridlist, 0)
}
}
func setGrid(board [][]byte, gridlist []Grid, index int) bool {
/*
try to fill allowed number
*/
if index >= len(gridlist) {
return true
}
cg := gridlist[index]
success := false
for _,v := range cg.allowds {
if isValidVal(board, cg.x, cg.y, v) {
board[cg.x][cg.y] = v
// fmt.Println("try:", cg[0], cg[1], v, "...")
if setGrid(board, gridlist, index+1) {
// fmt.Println("try:", cg[0], cg[1], v, "success")
success = true
break
}
}
}
// try failed back to 0/46
if !success {
board[cg.x][cg.y] = 46
}
return success
}
func isValidVal(board [][]byte, r int, c int, val byte) bool {
for i := 0; i < 9; i++ {
if board[i][c] == val {
return false
}
if board[r][i] == val {
return false
}
}
line_no := r / 3
col_no := c / 3
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if board[line_no*3+i][col_no*3+j] == val {
return false
}
}
}
return true
}
func getAllows(board [][]byte, r int, c int) []byte {
/*
r row
c col
*/
var allows []byte
digmap := make(map[byte]bool)
digmap[49] = false
digmap[50] = false
digmap[51] = false
digmap[52] = false
digmap[53] = false
digmap[54] = false
digmap[55] = false
digmap[56] = false
digmap[57] = false
// get row allow
for _, dig := range board[r] {
if dig != 46 {
digmap[dig] = true
}
}
// get col allow
for i := 0; i < 9; i++ {
dig := board[i][c]
if dig != 46 {
digmap[dig] = true
}
}
// get 3x3 allow
starti := (r / 3) * 3
startj := (c / 3) * 3
for i := starti; i < starti+3; i++ {
for j := startj; j < startj+3; j++ {
dig := board[i][j]
if dig != 0 {
digmap[dig] = true
}
}
}
for k := range digmap {
if !digmap[k] {
allows = append(allows, k)
}
}
// fmt.Println(r, c, "allowd:", allows)
return allows
}