小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目描述
请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独部分空格内已填入了数字,空白格用 '.' 表示。
注意:
一个有效的数独(部分已被填充)不一定是可解的。 只需要根据以上规则,验证已经填入的数字是否有效即可。
示例 1:
输入:board = [["5","3",".",".","7",".",".",".","."] ,["6",".",".","1","9","5",".",".","."] ,[".","9","8",".",".",".",".","6","."] ,["8",".",".",".","6",".",".",".","3"] ,["4",".",".","8",".","3",".",".","1"] ,["7",".",".",".","2",".",".",".","6"] ,[".","6",".",".",".",".","2","8","."] ,[".",".",".","4","1","9",".",".","5"] ,[".",".",".",".","8",".",".","7","9"]] 输出:true
思路
- 数独验证的问题可以将其转化为精确覆盖问题
- 将题目提供的三个要求转化为相互独立的要求
- 如果定义第i行,第j列的数字:num
- 对于要求一,可以划分为,数字num出现在第i行,那么也就是一共81个条件
- 要求二和要求三与要求一同理,共81*2=162个
于是我们使用一个长度为243的数组来记录一个条件是否满足。并通过行列数来计算得出该条件的下标
要求一:first = i+(num-1)*9要求二:second = 81+j+(num-1)*9- ``要求三:third = 162+(i/3)*3+j/3+(num-1)*9`
遍历二维数组,对于数字我们通过上面的计算式的结果作为数组下标,然后数值加一,最后遍历用于记录的数组,如果出现某个位置的值大于等于2.则说明该要求被重复满足了,则数独不合理
class Solution {
public boolean isValidSudoku(char[][] board) {
int[] judge = new int[243];
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
if(board[i][j]!='.') {
int num = (int)board[i][j]-48;
int first = i+(num-1)*9;
int second = 81+j+(num-1)*9;
int third = 162+(i/3)*3+j/3+(num-1)*9;
judge[first]++;
judge[second]++;
judge[third]++;
}
}
}
for(int i=0; i<243; i++){
if(judge[i]>=2){
return false;
}
}
return true;
}
}