解题思路
这是一个数独求解问题。使用回溯法,对每个空格位置尝试填入1-9的数字,直到找到一个合法解。
关键点:
- 判断数字在行、列、方格中是否合法
- 使用回溯法尝试填充空格
- 找到一个解即可返回
- 使用二维数组存储数独
算法步骤:
- 读入数独矩阵
- 找到空格位置
- 尝试填入数字
- 验证解的合法性
代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
bool isValid(vector<vector<int>>& board, int row, int col, int num) {
// 检查行
for (int x = 0; x < 9; x++) {
if (board[row][x] == num) return false;
}
// 检查列
for (int x = 0; x < 9; x++) {
if (board[x][col] == num) return false;
}
// 检查3x3方格
int startRow = row - row % 3;
int startCol = col - col % 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i + startRow][j + startCol] == num) return false;
}
}
return true;
}
bool solve(vector<vector<int>>& board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValid(board, i, j, num)) {
board[i][j] = num;
if (solve(board)) return true;
board[i][j] = 0;
}
}
return false;
}
}
}
return true;
}
public:
void solveSudoku(vector<vector<int>>& board) {
solve(board);
}
};
int main() {
vector<vector<int>> board(9, vector<int>(9));
// 读入数独
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cin >> board[i][j];
}
}
Solution solution;
solution.solveSudoku(board);
// 输出结果
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cout << board[i][j] << (j == 8 ? "\n" : " ");
}
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
private boolean isValid(int[][] board, int row, int col, int num) {
// 检查行
for (int x = 0; x < 9; x++) {
if (board[row][x] == num) return false;
}
// 检查列
for (int x = 0; x < 9; x++) {
if (board[x][col] == num) return false;
}
// 检查3x3方格
int startRow = row - row % 3;
int startCol = col - col % 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i + startRow][j + startCol] == num) return false;
}
}
return true;
}
private boolean solve(int[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValid(board, i, j, num)) {
board[i][j] = num;
if (solve(board)) return true;
board[i][j] = 0;
}
}
return false;
}
}
}
return true;
}
public void solveSudoku(int[][] board) {
solve(board);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[][] board = new int[9][9];
// 读入数独
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
board[i][j] = sc.nextInt();
}
}
Solution solution = new Solution();
solution.solveSudoku(board);
// 输出结果
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(board[i][j] + (j == 8 ? "\n" : " "));
}
}
sc.close();
}
}
class Solution:
def solve_sudoku(self, board: list) -> bool:
def is_valid(row: int, col: int, num: int) -> bool:
# 检查行
for x in range(9):
if board[row][x] == num:
return False
# 检查列
for x in range(9):
if board[x][col] == num:
return False
# 检查3x3方格
start_row = row - row % 3
start_col = col - col % 3
for i in range(3):
for j in range(3):
if board[i + start_row][j + start_col] == num:
return False
return True
def solve() -> bool:
# 找到一个空位置
for i in range(9):
for j in range(9):
if board[i][j] == 0:
# 尝试填入1-9
for num in range(1, 10):
if is_valid(i, j, num):
board[i][j] = num
if solve():
return True
board[i][j] = 0
return False
return True
solve()
return board
if __name__ == "__main__":
# 读入数独
board = []
for _ in range(9):
row = list(map(int, input().split()))
board.append(row)
solution = Solution()
result = solution.solve_sudoku(board)
# 输出结果
for row in result:
print(' '.join(map(str, row)))
算法及复杂度
- 算法:回溯法
- 时间复杂度:,其中 是空格数量
- 空间复杂度:,使用固定大小的数组