终于在2019的第一天赶上了第一篇博客
首先看看数独的规则
数独就是同一行不能有重复,同一列不能有重复,同一宫内不能有重复,
思考的时候也看了很多博客,写完发现并没有那么麻烦
其实知道了这些规则,就很好办了,总体采用回溯算法
首先把数独转换成二维数组
int[][] map =
{
{7,1,2,0,0,6,0,0,0},
{0,0,6,2,0,8,0,0,1},
{8,0,4,7,0,0,0,0,0},
{0,0,3,0,0,0,2,7,0},
{0,0,9,0,0,0,0,0,6},
{0,0,1,5,0,7,9,3,0},
{0,0,0,0,5,0,0,9,3},
{0,4,0,6,7,0,0,0,0},
{0,6,0,0,0,9,0,8,0}
};
用回溯首先就需要参数,当然就是空格子所在的行和列了
public void findResult(int row,int col){
for(int k = 1;k <=9;k++){
if(!hasSameInRow(row,k) && !hasSameInCol(col,k) && !hasSameInPalace(row,col,k)){
map[row][col] = k;
if(isEnd()){
printMap();
}
int[] a;
a= next(row,col);
findResult(a[0],a[1]);
map[row][col] = 0;
}
}
}
然后判断这个空格子该填什么数字,当然要从1开始尝试,一直试到9,
中间要考虑开头提到的三个条件,同一行同一列同一宫不能重复
//同一行有相同的返回true
public boolean hasSameInRow(int row,int x){
for(int i =0;i<map[row].length;i++){
if (x == map[row][i]) {
return true;
}
}
return false;
}
//同一列有相同的返回true
public boolean hasSameInCol(int col,int x){
for(int j = 0;j < map.length;j++){
if (x == map[j][col]) {
return true;
}
}
return false;
}
同一宫有点长,只放一部分吧
public boolean hasSameInPalace(int row,int col,int k){
if(row<3){
if(col<3){
for(int i = 0;i<3;i++){
for(int j = 0;j<3;j++){
if(map[i][j] == k){
return true;
}
}
}
}
else if(col<6){
。。。。。。。。
。。。。。。。。。
。。。。。。。。。。
return false
}
找到不重复的数字后,将其复值给这个空格子,然后检查是否填完,如果填完了,打印结果,否则寻找下一个空格子,开始递归
//判断是否填完
public boolean isEnd(){
for(int i = 0;i < map.length;i++){
for(int j = 0;j < map[i].length;j++){
if(map[i][j] == 0){
return false;
}
}
}
return true;
}
寻找下一个空格子其实也很简单,要么在本行,要么在下一行
//寻找下一个空格子
public int[] next(int row,int col){
//保存找到的空格子的行和列
int a[] = new int[2];
//在空格子在下一行的标志
boolean flag = true;
//遍历本行剩下的格子
for(int j = col;j<map[row].length;j++){
if (map[row][j] == 0){
a[0] = row;
a[1] = j;
flag = false;
break;
}
}
//在下一行找空格子
if(flag == true && row+1<9) {
for(int j = 0;j < map[row+1].length;j++){
if(map[row+1][j] == 0){
a[0] = row+1;
a[1] = j;
break;
}
}
}
return a;
}
很简单吧