LeetCode36-有效的数独 | 算法练习系列

592 阅读3分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

前言

js每日算法题,今日继续,今天依旧是一道数组处理的算法题,名字叫有效的数独,数独相信大家都玩过,数独的判断是非常复杂的,本题只对已经填写的数据进行判断,下面看题

题目描述

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)  

注意:

一个有效的数独(部分已被填充)不一定是可解的。 只需要根据以上规则,验证已经填入的数字是否有效即可。 空白格用 '.' 表示。  

示例 1:

image.png

输入: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
};

总结

本题是一道处理数组的问题,最终要的点就是要明确其中的三种情况,行,列,九宫格,然后遍历数组,哈希表来计数就可以了,本题的技巧性还是很强的