37. Sudoku Solver #
Problem #
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-9must occur exactly once in each row. - Each of the digits
1-9must occur exactly once in each column. - Each of the the digits
1-9must occur exactly once in each of the 93x3sub-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-9and the character'.'. - You may assume that the given Sudoku puzzle will have a single unique solution.
- The given board size is always
9x9.
Problem Summary #
Write a program to solve a Sudoku puzzle by filling the empty cells. A Sudoku solution must follow the rules below:
- The digits 1-9 can appear only once in each row.
- The digits 1-9 can appear only once in each column.
- The digits 1-9 can appear only once in each 3x3 box separated by thick solid lines.
Empty cells are indicated by ‘.’.
Solution Approach #
- Given a Sudoku puzzle, solve the Sudoku.
- Solution approach: DFS brute-force backtracking enumeration. Sudoku requires that the digits
1-9do not repeat in each row, each column, and each 3x3 box. Each time a number is placed, all 3 of these places need to be checked. - In addition, once one solution is found, there is no need to continue backtracking; just return directly.
Code #
package leetcode
type position struct {
x int
y int
}
func solveSudoku(board [][]byte) {
pos, find := []position{}, false
for i := 0; i < len(board); i++ {
for j := 0; j < len(board[0]); j++ {
if board[i][j] == '.' {
pos = append(pos, position{x: i, y: j})
}
}
}
putSudoku(&board, pos, 0, &find)
}
func putSudoku(board *[][]byte, pos []position, index int, succ *bool) {
if *succ == true {
return
}
if index == len(pos) {
*succ = true
return
}
for i := 1; i < 10; i++ {
if checkSudoku(board, pos[index], i) && !*succ {
(*board)[pos[index].x][pos[index].y] = byte(i) + '0'
putSudoku(board, pos, index+1, succ)
if *succ == true {
return
}
(*board)[pos[index].x][pos[index].y] = '.'
}
}
}
func checkSudoku(board *[][]byte, pos position, val int) bool {
// Check whether the row has duplicate numbers
for i := 0; i < len((*board)[0]); i++ {
if (*board)[pos.x][i] != '.' && int((*board)[pos.x][i]-'0') == val {
return false
}
}
// Check whether the column has duplicate numbers
for i := 0; i < len((*board)); i++ {
if (*board)[i][pos.y] != '.' && int((*board)[i][pos.y]-'0') == val {
return false
}
}
// Check whether the 3x3 box has duplicate numbers
posx, posy := pos.x-pos.x%3, pos.y-pos.y%3
for i := posx; i < posx+3; i++ {
for j := posy; j < posy+3; j++ {
if (*board)[i][j] != '.' && int((*board)[i][j]-'0') == val {
return false
}
}
}
return true
}