【每日算法】力扣36. 有效的数独

143 阅读3分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

描述

请你判断一个 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"]]

做题

刚看到这道题时,我觉得好难啊,要我去写数独?我连规则都不怎么会呢。

后面仔细看了一下,它只是要我们去判断当前写的数字是否是有效的,而不是去求解数独。

规则如下

每一行一个数字只能出现一次。

每一列一个数字只能出现一次。

单个九宫格内一个数字只能出现一次。

暴力破解法

思路

利用数组和哈希表,三个数组分别记录行、列、九宫格,数组的每个元素使用哈希表来记录当前行、列、九宫格 1 ~ 9 的数量,因为这里只记录 1 ~ 9 ,所以哈希表可以用数组代替,当重复时就返回 false。

记录行和列的数组是长度为 9 的。

记录九宫格的数组要使用 3x3 的二维数组(使用一维数组也不是不行,不过比较麻烦),9x9 的数组映射到 3x3 的数组上去,我们可以把坐标除以 3 来实现映射,x[i/3]y[j/3]。

这样我们每遍历一个数字,就可以在这三个数组中的元素数组相应的位置自增。

最后检查是否有计数大于 1,大于 1 就是无效的数独。

public boolean isValidSudoku(char[][] board) {
        int[][] lineCount = new int[9][9];
        int[][] columnCount = new int[9][9];
        int[][][] nineGongGeCount = new int[3][3][9];
        //后面的 [9] 就是用来记录 1~9 的出现次数的

        for(int i = 0;i < board.length;i++){
            for(int j = 0;j < board[i].length;j++){
                String c = String.valueOf(board[i][j]);
                if(".".equals(c)){
                    continue;
                }
                int num = Integer.parseInt(c) - 1;
                lineCount[i][num]++;
                columnCount[j][num]++;
                nineGongGeCount[i/3][j/3][num]++;
                //检验
                if(lineCount[i][num] > 1 || columnCount[j][num] > 1 || nineGongGeCount[i/3][j/3][num] > 1){
                    return false;
                }
            }
        }
        return true;
    }

image.png

最后

其他方法我也想不出来啦,等我以后够 np 了,再回来做!

今天就到这里了。

这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。