一、 问题描述:
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
二、解决思路:
看起来数独是个比较麻烦的问题,实际上在用程序模拟的时候是个比较简单的过程,类似于八皇后问题,可采用回溯的思想解决。
这里主要创建了三个boolean的数组分别来记录棋盘board的行、列、块的状态,并用一个linkedlist记录board中为空的格子的位置,提高扫描效率。
注意每次回溯之后恢复这些数组和容器的状态即可。
import java.util.*;
import java.io.*;
public class SudokuSolver {
public void solveSudoku(char[][] board) {
boolean[][] rowAppear = new boolean[9][9];
boolean[][] colAppear = new boolean[9][9];
boolean[][] blockAppear = new boolean[9][9];
List<Integer[]> list = new LinkedList<>();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char tmp = board[i][j];
if (tmp != '.') {
rowAppear[i][tmp-'1']=true;
colAppear[j][tmp-'1']=true;
blockAppear[i/3*3+j/3][tmp-'1']=true;
}
else {
list.add(new Integer[]{i,j});
}
}
}
helper(board, rowAppear, colAppear, blockAppear, list);
}
public boolean helper(char[][] board, boolean[][] rowAppear, boolean[][] colAppear, boolean[][] blockAppear, List<Integer[]> list) {
if (list.isEmpty()) {
return true;
}
Integer[] tmpPos = list.get(0);
int x=tmpPos[0], y=tmpPos[1];
list.remove(0);
for (int i = 0; i < 9; i++) {
if (!rowAppear[x][i] && !colAppear[y][i] && !blockAppear[x/3*3+y/3][i]) {
board[x][y] = (char)('1'+i);
rowAppear[x][i] = true;
colAppear[y][i] = true;
blockAppear[x/3*3+y/3][i] = true;
if (helper(board, rowAppear, colAppear, blockAppear, list)) return true;
board[x][y] = '.';
rowAppear[x][i] = false;
colAppear[y][i] = false;
blockAppear[x/3*3+y/3][i] = false;
}
}
list.add(0, tmpPos);
return false;
}
public static void main(String[] args) {
SudokuSolver sudokuSolver = new SudokuSolver();
char[][] board = new char[9][9];
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 9; i++) {
board[i] = scanner.next().toCharArray();
}
sudokuSolver.solveSudoku(board);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(board[i][j]+" ");
}
System.out.print("\n");
}
}
}