36.有效的数独(超级详细)(判断⼀个9x9的数独是否有效。只需要根据以下
规则,验证已经填。。。
####题⽬描述:
判断⼀个 9x9 的数独是否有效。只需要根据以下规则,验证已经填⼊的数字
是否有效即可。
1.数字 1-9 在每⼀⾏只能出现⼀次。
2.数字 1-9 在每⼀列只能出现⼀次。
3.数字 1-9 在每⼀个以粗实线分隔的 3x3 宫内只能出现⼀次。
要弄清楚这个问题,就是要知道验证的算法是什么.
1.验证每⼀⾏上⾯是否出现了重复的数字(1-9)
2.验证每⼀列上是否出现了重复的数字
3.验证每⼀个宫上⾯是否出现了重复的数字,
也就是说我们,要在两次循环(⼀次外循环,⼀次内循环)中进⾏这三次验证.
前提(如何去验证是否存在重复的数字?)
验证的⽅法就是使⽤数组,你想⼀下,总共9个数字,你在验证这个数字在⾏⾥⾯是否
已经出现了,你构建⼀个数组,长度为10,专门⽤来验证⾏的,假设验证的当前数字是5,
那么你就在这个数组⾥⾯索引为5的位置设置为1(代表出现过了),如果在验证当前⾏
时,别的列还出现了5,那么你判断这个数组索引为4的位置是否为1,如果是1,代表重复,
直接返回
还有⼀个需要强调的问题,就是如果只是使⽤两次循环的话,本来就只能够验证81个
数,只能验证9⾏中每⼀⾏是否有重复的数据.
但是现在要做的同时要验证3处,⾏是否重复,列是否重复,宫是否重复.
每⼀次验证,能得到的是坐标(i跟j),
只有⼀个坐标(i,j)要验证三处:
问题的解决:
验证⾏当前坐标的值是否在当前⾏⾥⾯重复出现过了.
for(int i = 0; i < 9; i++) {
int[] row = new int[9];
for(int j = 0; j < 9; j++) {
if(board[i][j] != '.') { // 当前的坐标是验证⾏的
if(row[board[i][j] - '1'] == 1) {
return fal;
} el {
row[board[i][j] - '1'] = 1;
}
}
}
循环到了(i,j)坐标,先获取这个值board[i][j],看⼀下这个值是否为'.',
先假设为6,开始时row这个数组的9个位置全是0,所以就会⾛
row[board[i][j] - '1'] = 1;
这段代码,然后数组的就变成了
[0, 0, 0, 0, 0, 1, 0, 0, 0] --- 这个数组此时的意义就是,当前⾏
存在6,因为索引为5的位置是1,代表6数字曾经在这⼀⾏出现过了.
注意这个数组是定义在这个内循环之外,外循环值内的,也就是说,当i为2时,换了⼀
⾏之后,就需要重新初始化.
需要注意的⼀点:
当在遍历第⼀⾏的数据是,(i,j)i的坐标全为0,说明是同⼀⾏,如果把i跟j的位置变换⼀下变成(j,i),那么i都是0,也就是说,变成了⼀列了,列的数字都是0,
验证当前的左边在这⼀列是否存在重复的元素
for(int i = 0; i < 9; i++){
int[] col = new int[9];
for(int j = 0; j < 9; j++) {
// 验证当前坐标的反置位置的元素是否在它的这⼀列存曾经出现过
if(board[j][i] != '.') { // 左边变成(j,i),就是验证列了
// 因为在这⼀次循环中,i都是不变的,变得都是j
if(col[board[j][i] - '1'] == 1) {
return fal;
} el {
col[board[j][i] - '1'] = 1;
}
}
}
// 在这个外循环⾥⾯,每⼀次变得都是j,
}
假设i = 2,说明遍历到了这个⼆维数组的第三⾏了,当吧左边反过来,也就是说这
⼀次遍历第2⾏元素时,列都是2,就变成了,这些元素都是第三列元素了,所以就可以
进⾏列上⾯的判断是否出现重复了.
验证当前元素在⼀个宫⾥⾯是否曾经出现过.
在解决这个问题之前,先看⼀个东西,宫是如何确定的.
现在需要分析的问题是:
现在假设遍历到了第三⾏数据,当你遍历第三⾏第⼀个数是,你需要将这个左边(2,0)
坐标转换,转换成,遍历当前⾏,的当前列的元素时,需要查询到这个坐标的数字,所在的宫的所有的元素.
看这个坐标转换的算法:
@Test
public void test01() {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
int cubeX = 3 * (i/3) + j/3;
int cubeY = 3 * (i%3) + j%3;
System.out.println("cubeX: " + cubeX + "- cubeY:" + cubeY);
}
System.out.println("----------------");
}
}
打印的结果:
cubeX: 0- cubeY:0 cubeX: 0- cubeY:1 cubeX: 0- cubeY:2 cubeX: 1- cubeY:0 cubeX: 1- cubeY:1 cubeX: 1- cubeY:2 cubeX: 2- cubeY:0 cubeX: 2- cubeY:1 cubeX: 2- cubeY:2 ----------------cubeX: 0- cubeY:3 cubeX: 0- cubeY:4 cubeX: 0- cubeY:5 cubeX: 1- cubeY:3 cubeX: 1- cubeY:4 cubeX: 1- cubeY:5 cubeX: 2- cubeY:3 cubeX: 2- cubeY:4 cubeX: 2- cubeY:5 ----------------cubeX: 0- cubeY:6 cubeX: 0- cubeY:7 cubeX: 0- cubeY:8 cubeX: 1- cubeY:6 cubeX: 1- cubeY:7 cubeX: 1- cubeY:8 cubeX: 2- cubeY:6 cubeX: 2- cubeY:7 cubeX: 2- cubeY:8 ----------------cubeX: 3- cubeY:0 cubeX: 3- cubeY:1 cubeX: 3- cubeY:2 cubeX: 4- cubeY:0 cubeX: 4- cubeY:1 cubeX: 4- cubeY:2 cubeX: 5- cubeY:0 cubeX: 5- cubeY:1 cubeX: 5- cubeY:2 ----------------cubeX: 3- cubeY:3 cubeX: 3- cubeY:4 cubeX: 3- cubeY:5 cubeX: 4- cubeY:3 cubeX: 4- cubeY:4 cubeX: 4- cubeY:5 cubeX: 5-
cubeY:3 cubeX: 5- cubeY:4 cubeX: 5- cubeY:5 ----------------cubeX: 3- cubeY:6 cubeX: 3- cubeY:7 cubeX: 3- cubeY:8 cubeX: 4- cubeY:6 cubeX: 4- cubeY:7 cubeX: 4- cubeY:8 cubeX: 5- cubeY:6 cubeX: 5- cubeY:7 cubeX: 5- cubeY:8 ----------------cubeX: 6- cubeY:0 cubeX: 6- cubeY:1
cubeX: 6- cubeY:2
cubeX: 7- cubeY:0
cubeX: 7- cubeY:1
cubeX: 7- cubeY:2
cubeX: 8- cubeY:0
cubeX: 8- cubeY:1
cubeX: 8- cubeY:2
----------------
cubeX: 6- cubeY:3
cubeX: 6- cubeY:4
cubeX: 6- cubeY:5
cubeX: 7- cubeY:3
cubeX: 7- cubeY:4
cubeX: 7- cubeY:5
cubeX: 8- cubeY:3
cubeX: 8- cubeY:4
cubeX: 8- cubeY:5
----------------
cubeX: 6- cubeY:6
cubeX: 6- cubeY:7
cubeX: 6- cubeY:8
cubeX: 7- cubeY:6
cubeX: 7- cubeY:7
cubeX: 7- cubeY:8
cubeX: 8- cubeY:6
cubeX: 8- cubeY:7
cubeX: 8- cubeY:8
----------------
分析:
当循环⾛到i=2时,遍历到的是第三⾏的数据
当 i = 2 , j = 0时 cubeX: 0- cubeY:6
这个坐标是第三宫(宫⼆)的第⼀个元素(0,6)
当 i = 2 , j = 1时 cubeX: 0- cubeY:7
这个坐标是第三宫(宫⼆)的第⼆个元素(0,7)
当 i = 2, j = 2时 cubeX: 0- cubeY:8
这个坐标是第三宫(宫⼆)的第三个元素(0,8)
当 i = 2 , j = 3时 cubeX: 1- cubeY:6
这个坐标是第三宫(宫⼆)的第四个元素(1,6)
当 i = 2 , j = 4时 cubeX: 1- cubeY:7
这个坐标是第三宫(宫⼆)的第五个元素(1,7)
当 i = 2, j = 5时 cubeX: 1- cubeY:8
这个坐标是第三宫(宫⼆)的第六个元素(1,8)
当 i = 2 , j = 6时 cubeX: 2- cubeY:6
这个坐标是第三宫(宫⼆)的第七个元素(2,6)
当 i = 2 , j = 7时 cubeX: 2- cubeY:7
这个坐标是第三宫(宫⼆)的第⼋个元素(2,7)
当 i = 2, j = 8时 cubeX: 2- cubeY:8
这个坐标是第三宫(宫⼆)的第九个元素(2,8)
也就睡说当外循环⾛到i = 2 时间,课可以对宫⼆的元素进⾏判断是否存在重复事务元素关键是将坐标(i,j)变成宫i的所有的坐标
*所以验证宫的做法就是:*