leetcode36 有效的数独【中等难度】
英文题目: Valid sudoku
难度: 中等
请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字
1-9在每一行只能出现一次。数字
1-9在每一列只能出现一次。数字
1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
示例 1:

示例 2:
提示:
board.length == 9board[i].length == 9board[i][j]是一位数字或者'.'
分析
方法1、蛮力直接法
使用set, 对于行遍历: 每一行中, isValid: unique的数字数量+'.'的数量 = 9, 对于列遍历:每一列中, isValid: unique的数字数量+'.'的数量 = 9, 对于box遍历:每个3行3列九宫格中,isValid: unique的数字数量+'.'的数量 = 9。
已AC代码:
跟国外的小伙伴想到一块去了。 https://leetcode.com/problems/valid-sudoku/discuss/869625/easy-C%2B%2B-with-set
方法2:set插入方法 - 改进
坐标中任意一点(i,j),可以map到对应的的第几行第几列的方块(box)中,box的坐标为(i/3, j/3)。
于是把一个小的九宫格中的数全压缩到一个box中,比如:

以最中间那个九宫格为例,使用int型的/3可以得到:

对于任意一个值不为'.'的字符,进行如下操作:
1.把所在row的信息插入到大九宫格中;
2.把所在column的信息插入到大九宫格中;
3.把所在的小方块(box)的信息插入到大九宫格中。
插入如果失败说明出现了重复。
已AC的C++代码:
Java的HashSet有同样的写法,Java中插入失败,会出现 set.Add() == false。
方法3:使用位操作
此题,使用位操作,是几种解法中速度最快的算法了。
具体做法是:

将大数独棋盘分成9个小棋盘,编号0~8。
窗口中的每个小方格若有数字,必为 1 ~ 9 (记作k),该方法适用于 遍历行/遍历列/遍历box。
然后把 二进制数 1 左移 k 位,得到偏移量shift,后续使用按位或|来判断是否存在。
已AC的C++代码:
后两种方法,参考:
https://www.youtube.com/watch?v=ceOLAY4XUOw&ab_channel=JacobHuang
最后更新于
这有帮助吗?