思路
- 要建立几个数组:存测试样例,存横、竖、3*3宫格,存1-9的bool等
- 最上方的行i=0,最左边的列j=0
- 从上到下,从左到右,一次检查一个格子,先求出这个格子还剩什么数字可以填,然后检查横、竖、33宫格是否都满足?如果是,就检查33宫格的其他两行是否都满足,“都满足就填数(这里是有问题①的)”,不是就换一个数,从头再来。
- 最后检查9*9宫格是否都满足。
①:这种情况遇到同一行有多个格子满足的情况是可能会填错数。
——解决方法参考:换一个数,或往下一个格子/下一行填(那就要有9行重复填的行为了相当于会的就填,不会的不填,然后倒回来,之前不会填的就能填了)
参考的答案用到了dfs和hashset来保证数字不重复。
没有代码,没时间写了。
以下代码为牛客用户所写,他的主页:
VagrantYang的牛客主页
import java.util.*;
/**
* 华为03-数独
*
* 此题思路就是dfs,假定空白处为某值,然后依据这个条件纵向求解
* 若不满足,则回溯,改变该值,继续纵向,找到结果后
* 用一个变量告诉后面的回溯的过程,使其结束递归,即剪枝
*
* 注意一点是:即使该点不为空,也要继续递归考察下一个节点
* 我就是忘了这一步,调试了好大会,55555
*
* 索引的增长:
* 1.可以使用x,y来保存,y每一步都要加1,而x根据y是否走到末尾来决定是否换行
* 2.可以使用一个变量index来保存,index / 9 即行数,index % 则列数
* Create by Special on 2018/3/2 13:38
*/
public class Main {
static int[][] nums = new int[9][9];
static boolean isOk;
private static boolean isValid(int x, int y){
for(int i = 0; i < 9; i++){
if(i != y){
if(nums[x][i] == nums[x][y]){
return false;
}
}
if(i != x){
if(nums[i][y] == nums[x][y]){
return false;
}
}
}
/**
* 通过以下可以找到x,y所处的9宫格的第一个节点的行列索引
*/
int row = (x / 3) * 3;
int col = (y / 3) * 3;
for(int i = row; i < row + 3; i++){
for(int j = col; j < col + 3; j++){
if(i != x && j != y){
if(nums[i][j] == nums[x][y]){
return false;
}
}
}
}
return true;
}
public static void dfs(int x, int y) {
if(x == 9 && y == 0){
isOk = true;
return;
}
int tempY = y + 1, tempX = x;
if(tempY == 9){
tempY = 0;
tempX += 1;
}
if(nums[x][y] != 0){
dfs(tempX, tempY);
}else {
for(int i = 1; i <= 9; i++) {
nums[x][y] = i;
if(isValid(x, y)){
dfs(tempX, tempY);
if(isOk){
return;
}
}
nums[x][y] = 0;
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNext()){
isOk = false;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
nums[i][j] = input.nextInt();
}
}
dfs(0,0);
/**
* 因为数独不唯一,所以为了AC,只能如此,打印出测试用例的特例
*/
// if(nums[6][0]==2&&nums[6][1]==1&&nums[6][2]==3)
{
nums[6][2]=5;nums[6][3]=8;nums[6][4]=4;nums[6][5]=6;nums[6][6]=9;nums[6][7]=7;nums[6][8]=3;
nums[7][0]=9;nums[7][1]=6;nums[7][2]=3;nums[7][3]=7;nums[7][4]=2;nums[7][5]=1;nums[7][6]=5;nums[7][7]=4;nums[7][8]=8;
nums[8][0]=8;nums[8][1]=7;nums[8][2]=4;nums[8][3]=3;nums[8][4]=5;nums[8][5]=9;nums[8][6]=1;nums[8][7]=2;nums[8][8]=6;
}
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
System.out.print((j == 0 ? "" : " ") + nums[i][j]);
}
System.out.println();
}
}
}
}