思路
- 定义三个标记数组,分别标记行、列、以及3*3块中各个数字的出现情况
- 遍历这个矩阵,当遍历的位置上是数字时,进行判断
- 如果在任意一行、一列、或一个块中出现过这个数字,说明这个数组无效,返回false
- 如果没有这个数字出现,则在对应一行、一列、或一个块中将这个数组标识为已出现(true) - 如果遍历结束,都没有重复数字的出现,这说明数独有效,返回true
但是,对于块的计算规则有些特殊:这里的计算规则为 int blockFlag = i / 3 * 3 + j / 3;
- 将每个3 * 3的九宫格看成一组,这样就有一个大的 3 * 3 的数组
- i 所代表的的就是大的数组的行,j代表大数组的列(3个小方块为一列)
- 即 i = 0 1 2 为前三个block;3 4 5 为中间三个block;6 7 8 为最下面的三个block
- 即 j = 0 1 2 为一组;j = 3 4 5 为一组;j = 6 7 8 为一组
代码实现(java)
class Solution {
public boolean isValidSudoku(char[][] board) {
boolean[][] row = new boolean[9][9];
boolean[][] col = new boolean[9][9];
boolean[][] block = new boolean[9][9];
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(board[i][j] != '.') {
int num = board[i][j] - '1';
// 将每个3 * 3的九宫格看成一组,这样就有一个大的 3 * 3 的数组
// i 所代表的的就是大的数组的行,j代表大数组的列(3个小方块为一列)
// 即 i = 0 1 2 为前三个block;3 4 5 为中间三个block;6 7 8 为最下面的三个block
// 即 j = 0 1 2 为一组;j = 3 4 5 为一组;j = 6 7 8 为一组
int blockFlag = i / 3 * 3 + j / 3;
if(row[i][num] || col[j][num] || block[blockFlag][num]) {
return false;
} else {
row[i][num] = true;
col[j][num] = true;
block[blockFlag][num] = true;
}
}
}
}
return true;
}
}