题意:对于一个九宫格,对九个格子每一个都再划分九宫格,总共81小格子。现在要满足规则:对整个格子区域每横有且仅有1-9,每列亦然。而对于每个一级九宫格里面的九个二级九宫格,有且仅有1-9(总共三条规则)。
给出一个char[][]数组,判断是否可解。('.' 代表空格子)。
初步分析:
三个条件实质上其实就是不能重复,自然想到set这种集合,最大的特点就是元素不能重复。初步的思路是对于这三者规则(每一行,每一列,每一个小九宫格),用set来存储其中的元素。对于不空的元素(已经给出的元素),判断加进去重不重复,不重复就加进去,如果重复就返回false。对于一次二重循环,一行一列都很好描述,难的是对于一个小九宫格的遍历。
我们还是按照从左到右从上到下的顺序来遍历九宫格,我们发现,规律是三个一组,三个一组的。i从0-8分别代表1-9个九宫格。明显0、3、6和1、4、7和2、5、8是类似的。
对于036号九宫格:j=012的时候i不变,j不变,j=345的时候i+1,j-3,j=678的时候i+2,j-6
对于147号九宫格:j=012的时候i-1,j+3,j=345的时候i不变,j不变,j=678的时候i+1,j-3
对于258号九宫格:j=012的时候i-2,j+6,j=345的时候i-1,j+3,j=678的时候i不变,j不变
=>
i % 3 = 0时:i = i + j/3 j = j - 3*(j/3)
i % 3 = 1时: i = i + j/3 - 1; j = j - 3*(j/3) + 3
i % 3 = 2时: i = i + j/3 - 2; j = j - 3*(j/3) + 6
=>
i = i + j/3 - i%3; j = j - 3*(j/3) + 3*(i%3);
public class Solution {
public boolean isValidSudoku(char[][] board) {
for(int i = 0; i<9; i++){
HashSet<Character> row = new HashSet<Character>();
HashSet<Character> col = new HashSet<Character>();
HashSet<Character> cub = new HashSet<Character>();
for (int j = 0; j < 9;j++){
if(board[i][j]!='.' && !row.add(board[i][j]))
return false;
if(board[j][i]!='.' && !col.add(board[j][i]))
return false;
if(board[ i + j/3 - i%3][ j - 3*(j/3) + 3*(i%3)]!='.' && !cub.add(board[ i + j/3 - i%3][ j - 3*(j/3) + 3*(i%3)]))
return false;
}
}
return true;
}
}