解数独(Sudoku Solver)

📌 定义

编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:

  1. 数字 1-9 在每一行只能出现一次
  2. 数字 1-9 在每一列只能出现一次
  3. 数字 1-9 在每一个 3×3 宫内只能出现一次

空白格用 '.' 表示。

示例:
输入:
[["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"]]

输出:
[["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"]]

核心思路

使用回溯算法逐个填充空格:

  • 选择:在空格中尝试填入 1-9
  • 约束:检查是否满足数独规则
  • 探索:递归填充下一个空格
  • 撤销:如果无解,回溯尝试其他数字

复杂度分析

指标复杂度说明
时间复杂度O(9^m)m是空格数
空间复杂度O(1)原地修改

Go 代码

Go 实现

func solveSudoku(board [][]byte) {
    backtrack(board)
}
 
func backtrack(board [][]byte) bool {
    for i := 0; i < 9; i++ {
        for j := 0; j < 9; j++ {
            if board[i][j] != '.' {
                continue
            }
 
            for num := byte('1'); num <= '9'; num++ {
                if isValid(board, i, j, num) {
                    board[i][j] = num
 
                    if backtrack(board) {
                        return true
                    }
 
                    board[i][j] = '.'
                }
            }
 
            return false
        }
    }
    return true
}
 
func isValid(board [][]byte, row, col int, num byte) bool {
    for i := 0; i < 9; i++ {
        if board[row][i] == num {
            return false
        }
        if board[i][col] == num {
            return false
        }
 
        boxRow := (row/3)*3 + i/3
        boxCol := (col/3)*3 + i%3
        if board[boxRow][boxCol] == num {
            return false
        }
    }
    return true
}

思路展开

约束检查详解

检查(4,4)位置是否可以填5:

1. 检查第4行:
   [4,.,.,8,.,3,.,.,1]
   没有5 ✓

2. 检查第4列:
   [7,9,.,6,.,2,.,1,8]
   没有5 ✓

3. 检查中间3×3宫格:
   [.,.,.]
   [8,.,3]
   [.,2,.]
   没有5 ✓

结果: 可以填5

经典题目

LeetCode 问题

相关主题


返回:回溯算法 | 算法学习导航