Leetcode 36. 有效的数独

181 阅读3分钟

Leetcode 36. 有效的数独

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

❤️‍欢迎订阅java厂长《LeetCode每日一题》 ❤️‍

1、题目📑

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

如果数组中不存在目标值 target,返回 [-1, -1]

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
  • 注意:
    • 一个有效的数独(部分已被填充)不一定是可解的。
    • 只需要根据以上规则,验证已经填入的数字是否有效即可。
    • 空白格用 '.' 表示。

实例1

img

输入: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 存在, 因此这个数独是无效的。

提示

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字(1-9)或者 '.'

2、思路🧠

方法一:就按照从左往右、从上往下的顺序遍历一次board,完成数独的三个条件即可

本题的难点在于在看到题目中的条件1,条件2还是比较好分析出来的,条件3就是比较有难度了。

image-20220609233448643

将图中的3❌9分为3个区域,ij 可以唯一确定属于哪个区域,例如 box[1] [1]一定属于区域1,box[4] [2]一定属于区域2。

  • 通过上述的规律发现box只取决于纵坐标,纵坐标【0、1、2】属于区域1,纵坐标【3、4、5】属于区域2,纵坐标【6、7、8】属于区域3,得出规律也就是 纵坐标 / 3
  • 但是题目给的是9 ❌9分为9个区域,此时需要考虑到横坐标的关系,这里的思想类似于推到纵坐标的思想,得出规律也就是 横坐标 / 3

分析题目得到该题需要用三个维度进行解题,所在的行,所在的列,所在的box,注意box的下标也是从左往右、从上往下的。

在遍历每个数的时候,需要满足三个条件:

  • 在第 i 个行中是否出现重复数字
  • 在第 j 个列中是否出现重复数字
  • 在第 (i/3) * 3 + j/3 个box中是否出现过

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

class Solution {
    public boolean isValidSudoku(char[][] board) {
        // 整个board有9行,第二维的维数10是为了让下标有9,和数独中的数字9对应。
        int [][]row  =new int[9][10];
        int [][]col  =new int[9][10];
        int [][]box  =new int[9][10];
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j]=='.') continue;

                int curNum = board[i][j]-'0';

                if (row[i][curNum]==1) return false;
                
                if (col[j][curNum]==1) return false;
                
                if (box[j/3 + (i/3) * 3][curNum]==1) return false;

                row[i][curNum]=1;
                col[j][curNum]=1;
                box[(i/3) * 3 + j/3][curNum] = 1;
            }
        }
        return true;
    }
}

时间复杂度:O(N2)

空间复杂度:O(1)

image-20220609235458401

4、总结

该题目的对思维的分析与探讨,对于数独的解法在计算机中是必须要学会的解决数学问题的一种情景,用计算机高强度的运算能力,来解决数学问题。

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:36. 有效的数独 - 力扣(LeetCode)