这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
前言
js每日算法题,今日继续,今天依旧是一道数组处理的算法题,名字叫有效的数独,数独相信大家都玩过,数独的判断是非常复杂的,本题只对已经填写的数据进行判断,下面看题
题目描述
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 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
示例 2:
输入:board =
[["8","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"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
解题思路
- 本题的主要思路是判断三种条件,1.判断每行中是否存在相同的项2.判断每列中是否存在相同的项3.判断每一个小的九宫格中是否存在相同的项
- 本题只需要遍历一遍目标数组就行了,使用哈希表来记录每次遍历的数字出现的次数,由于每个项的大小一定在1-9之间,那么这里就用数组来代替哈希表来计数
- 首先声明三个数组,分别用来记录行,列以及小九宫格中出现次数,然后遍历目标数组,由于每项的值必在1-9之间,这里我们就可以用目标数组的项-1来当做下标,下标对应的项就是我们所计的数,其中行,列是二维数组,小九宫格是三维数组,下面看代码
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
let rowArr = new Array(9).fill(0).map(()=>new Array(9).fill(0)) //行的计数数组
let columnArr = new Array(9).fill(0).map(()=> new Array(9).fill(0)) //列的计数数组
let squareArr = new Array(3).fill(0).map(()=> new Array(3).fill(0).map(()=>new Array(9).fill(0))) //九宫格的计数数组(三维数组)
for(let i=0;i<9;i++){
for(let j=0;j<9;j++){
const curr = board[i][j]
if(curr!=='.'){
const index = Number(curr)-1 //当前项减1当做计数数组的下标
rowArr[i][index]++
columnArr[j][index]++
squareArr[Math.floor(i/3)][Math.floor(j/3)][index]++
//如果有相同的项,那index必然相等,这里只要判断计数项是不是大于1就可以了
if (rowArr[i][index] > 1 || columnArr[j][index] > 1 || squareArr[Math.floor(i/3)][Math.floor(j/3)][index] > 1){
return false;
}
}
}
}
return true
};
总结
本题是一道处理数组的问题,最终要的点就是要明确其中的三种情况,行,列,九宫格,然后遍历数组,哈希表来计数就可以了,本题的技巧性还是很强的