描述
问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
输入
粘贴失败
输出
粘贴失败
数据范围:输入一个 9*9 的矩阵
输入描述:
包含已知数字的9X9盘面数组[空缺位以数字0表示]
输出描述:
完整的9X9盘面数组
示例1
输入:
0 9 2 4 8 1 7 6 3 4 1 3 7 6 2 9 8 5 8 6 7 3 5 9 4 1 2 6 2 4 1 9 5 3 7 8 7 5 9 8 4 3 1 2 6 1 3 8 6 2 7 5 9 4 2 7 1 5 3 8 6 4 9 3 8 6 9 1 4 2 5 7 0 4 5 2 7 6 8 3 1
输出:
5 9 2 4 8 1 7 6 3 4 1 3 7 6 2 9 8 5 8 6 7 3 5 9 4 1 2 6 2 4 1 9 5 3 7 8 7 5 9 8 4 3 1 2 6 1 3 8 6 2 7 5 9 4 2 7 1 5 3 8 6 4 9 3 8 6 9 1 4 2 5 7 9 4 5 2 7 6 8 3 1
通过全部用例
运行时间17ms
占用内存9588KB
//创建二维数组
int[][] sudu = new int[9][9];
//遍历每一个元素
for (int[] row : sudu) {
String str = br.readLine();
//分隔每一行为一个字符串数组,长度为1
String[] strs = str.split(" ");
for (int j = 0; j < strs.length; j++) {
//把长度为1的字符串数组变成int类型
row[j] = Integer.parseInt(strs[j]);
}
}
//判断数独是否添加完成
if (backTracking(sudu)) {
//二维数组遍历
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
//输出一行数字
System.out.print(sudu[i][j] + " ");
}
//下一行之前换行
System.out.println("");
}
} else {
//未完成时的提示
System.out.println("未知错误!");
}
}
public static boolean backTracking(int[][] sudo) {
//遍历数组的每一个元素
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
//如果当前元素为0,则需要重新赋值
if (sudo[i][j] == 0) {
//循环填数字
for (int k = 1; k <= 9; k++) {
//判断填入数字是否符合要求
if (isValid(i, j, k, sudo)) {
//填数字
sudo[i][j] = k;
//递归
if (backTracking(sudo)) {
return true;
}
//回溯,如果当前元素赋值失败,准备重新赋值
sudo[i][j] = 0;
}
}
return false;//如果没有符合要求的数字返回false
}
}
}
//每个元素都赋值之后则返回为true
return true;
}
//验证元素是否重复的方法
public static boolean isValid(int row, int col, int k, int[][] sudo) {
//检查行是否已经有相同的元素
for (int i = 0; i < 9; i++) {
if (sudo[row][i] == k) {
return false;
}
}
//检查列是否已经有相同的元素
for (int i = 0; i < 9; i++) {
if (sudo[i][col] == k) {
return false;
}
}
//定义小九宫格的起始坐标(0,0)或者(0,3).....
int startRow = (row / 3) * 3;
int endCol = (col / 3) * 3;
//检查九宫格中是否已经有相同的元素
for (int i = startRow; i < startRow + 3; i++) {
for (int j = endCol; j < endCol + 3; j++) {
if (sudo[i][j] == k) {
return false;
}
}
}
return true;
}