检测一个数独是否valid,注意数独是一个9 x 9的方格,在每一行每一列和每一个3 x 3的小正方形中,都必须出现从1到9的九个数字。
由数独的性质而来,我们可以思考出检测一个数独是否valid的方法,就是分别对每一行每一列和每个3 x 3的小正方形进行检查,每一行每一列的检查方法较为容易,关键在于9个小正方形中数字的检查。这里我们用到了/,%运算的一些性质,对于一个从0-8的数字i,i / 3的值是0 0 0 1 1 1 2 2 2,i % 3的值是0 1 2 0 1 2 0 1 2,可以发现这与一个3 x 3的小正方形中各个数字坐标的位置高度重合。而由于数独相当于是二维数组,所以求解这道题目的过程中我们也一定会用到二重循环,也就是说在一个从0到8的循环当中,我们就可以使用内层变量j检测完一个小正方形。
那么对于其他的小正方形我们怎么办呢?答案就是对i使用同样的方法,将其作为每个小矩阵相对于整体大矩阵的index,也就是左上角元素的index,可以设置
rowIndex = 3 * (i / 3);
colIndex = 3 * (i % 3);
这样就能够在i从0到8的循环中得出九个小矩阵相对于整体大矩阵的index。时间复杂度为O(n ^ 2),代码如下:
public class Solution {
public boolean isValidSudoku(char[][] board) {
for(int i = 0; i < 9; i++){
Set<Character> rows = new HashSet<Character>();
Set<Character> columns = new HashSet<Character>();
Set<Character> cube = new HashSet<Character>();
for(int j = 0; j < 9; j++){
// Check row
if(board[i][j] != '.' && !rows.add(board[i][j])){
return false;
}
// Check column
if(board[j][i] != '.' && !columns.add(board[j][i])){
return false;
}
// Check cube
int rowIndex = 3 * (i / 3); // row index of current cube
int colIndex = 3 * (i % 3); // col index of current cube
if(board[rowIndex + j / 3][colIndex + j % 3] != '.' &&
!cube.add(board[rowIndex + j / 3][colIndex + j % 3])){
return false;
}
}
}
return true;
}
}
知识点:
1. 注意在矩阵中利用/和%运算得到矩阵中元素index的技巧
2. Java中实现了Set接口的集合的add方法如果不成功的话,返回的是false,成功则为true