public class SoduTest {
private int[][] sodu = {
// 最难的
// {0,0,5,3,0,0,0,0,0},
// {8,0,0,0,0,0,0,2,0},
// {0,7,0,0,1,0,5,0,0},
// {4,0,0,0,0,5,3,0,0},
// {0,1,0,0,7,0,0,0,6},
// {0,0,3,2,0,0,0,8,0},
// {0,6,0,5,0,0,0,0,9},
// {0,0,4,0,0,0,0,3,0},
// {0,0,0,0,0,9,7,0,0}
// 包含两个解的
{7,6,1,2,4,5,8,3,9},
{3,2,8,1,7,9,4,5,6},
{0,0,4,8,3,6,7,2,1},
{8,7,5,9,6,4,2,1,3},
{2,3,9,7,5,1,6,4,8},
{1,4,6,2,8,3,9,7,5},
{4,1,7,3,9,8,5,6,2},
{0,0,3,4,2,6,1,8,7},
{6,8,2,5,1,7,3,9,4}
};
public static void main(String[] args) {
long timeStart = System.currentTimeMillis();
new SoduTest().getSoduAnswer(0, 0);
long timeStop = System.currentTimeMillis();
System.out.println("It took " + (timeStop - timeStart) + " milliseconds");
}
/**
* 核心算法,利用递归回溯,求出所有解
* @param x 起始第 x 行
* @param y 起始第 y 列
* @return
*/
private boolean getSoduAnswer(int x, int y) {
if(y == 9) {
// 终止条件
if(x == 8) {
// 打印
printSodu(this.sodu);
System.out.println("-------------------------------------------");
// 若返回true,则求出一个解后退出
// return true;
// 若返回false,则求出一个解后向前回溯,直到求出所有解
return false;
}
// 换行
x++;
y = 0;
}
// 如果不为0,直接计算下一个数
if(this.sodu[x][y] != 0) {
return getSoduAnswer(x, y+1);
}
// 尝试 1-9 是否满足条件
for(int i = 1; i <= 9; i++) {
if(this.checkSoduNum(x, y, i)) {
//满足条件设置值
this.sodu[x][y] = i;
//并尝试下一个数是否满足条件
if(getSoduAnswer(x, y+1)) {
return true;
}else {
// 若不满足条件,进行回溯
this.sodu[x][y] = 0;
}
}
}
return false;
}
/**
* 判断值是否合理
* @param x
* @param y
* @param soduNum
* @return
*/
private boolean checkSoduNum(int x, int y, int soduNum) {
// 判断当前行,列是否有重复
for(int i = 0;i < 9;i++) {
if(this.sodu[x][i] == soduNum) {
return false;
}
if(this.sodu[i][y] == soduNum) {
return false;
}
}
// 求出左上角坐标
int a = x - (x % 3);
int aStop = a+3;
int b = y - (y % 3);
int bStop = b+3;
// 判断当前方框内是否有重复
for(a = x - (x % 3);a<aStop;a++) {
for(b = y - (y % 3);b<bStop;b++) {
if(this.sodu[a][b] == soduNum) {
return false;
}
}
}
return true;
}
/**
* 打印数组
* @param sodu
*/
public static void printSodu(int[][] sodu) {
for(int i = 0; i < sodu.length; i++) {
int[] soduX = sodu[i];
for(int j = 0; j < soduX.length; j++) {
int soduY = soduX[j];
if(j != 0 && j % 3 == 0) {
System.out.print(" ");
}
System.out.print(soduY);
}
System.out.println();
if(i != 0 && (i+1) % 3 == 0) {
System.out.println();
}
}
}
}
原文:https://www.cnblogs.com/gode/archive/2019/06/17/11039367.html