public class SudokuDemo {
public static void main(String[] args) {
// 数独
sudoku();
}
public static void sudoku() {
long start = System.currentTimeMillis();
int[][] num = { { 0, 5, 7, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 4, 7, 0, 0, 0 },
{ 0, 0, 0, 0, 8, 0, 0, 6, 2 },
{ 7, 0, 0, 0, 0, 0, 9, 1, 0 },
{ 3, 0, 5, 6, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 8, 0 },
{ 0, 0, 8, 0, 0, 9, 0, 0, 1 },
{ 0, 0, 4, 0, 0, 2, 3, 0, 9 },
{ 0, 6, 0, 0, 0, 0, 8, 0, 0 } };
int x = 0, y = 0;
int r = ans(num, x, y);
long end = System.currentTimeMillis();
System.out.println("一共耗时 " + (end - start) + " ms");
if (r != 0) {
System.out.println("没有解。。。");
return;
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(num[i][j] + " ");
}
System.out.println();
}
}
private static int ans(int[][] num, int x, int y) {
if (x >= 9 || y >= 9) {
return 0;
}
// 查找对应的空白域
if (num[x][y] != 0) {
// 下一个空白域
int[] curPos = nextEmptyPos(num, x, y);
if (curPos[0] >= 9) {
return 0;
}
x = curPos[0];
y = curPos[1];
}
for (int rs = 1; rs <= 9; rs++) {
// 检查横、竖
if (!checkHorizontalOrVertical(num, rs, x, y)) {
continue;
}
// 内部9宫格
if (!checkInnerNine(num, rs, x, y)) {
continue;
}
// 目标值
num[x][y] = rs;
// 下一个空白域
int[] next = nextEmptyPos(num, x, y);
if (next[0] >= 9) {
return 0;
}
int nx = next[0], ny = next[1];
// 下一个值
int r = ans(num, nx, ny);
// 没找到,复位,回溯
if (r == -1) {
num[x][y] = 0;
continue;
}
// 结束
if (r == 0) {
return 0;
}
}
// 没找到,回溯
return -1;
}
private static boolean checkHorizontalOrVertical(int[][] num, int target,
int x, int y) {
for (int i = 0, j = 0; i < 9 || j < 9; i++, j++) {
if (target == num[x][i] || target == num[j][y]) {
return false;
}
}
return true;
}
private static boolean checkInnerNine(int[][] num, int target, int x,
int y) {
int offsetX = x / 3, offsetY = y / 3;
int startX = offsetX * 3, startY = offsetY * 3;
int endX = startX + 3, endY = startY + 3;
for (int i = startX, j = startY; i < endX; j++) {
if (target == num[i][j]) {
return false;
}
// 内部9宫格下一行
if (endY - 1 == j) {
i++;
j = startY - 1;
}
}
return true;
}
private static int[] nextEmptyPos(int[][] num, int x, int y) {
do {
y++;
if (y >= 9) {
x++;
y = 0;
}
} while (x < 9 && num[x][y] != 0);
return new int[] { x, y };
}
}