有效的数独 (LeetCode)

请你判断一个
9 x 9
的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字
1-9
在每一行只能出现一次。数字
1-9
在每一列只能出现一次。数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。(请参考示例图)
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用
'.'
表示。
解题代码
思路来源为题解区大佬, 最开始只能想到暴力法。然后一直在找取巧的思路,但是无果,只好去题解区逛逛,然后就发现了这个

经过大半天的借鉴,终于看懂了思路。
思路如下:
首先声明三个数组,长度为9,分别为:行,列,块。即九行、九列、九个九宫格。之所以这么声明巧的就是接下来的。
题目要求,每行、每列、每个九宫格 都不能有重复数字。所以需要检测每行每列每个九宫格。
然后,int 类型 C# 中 有四个字节,即 32 位,也就是 32 个 可为 01 。所以,可根据位运算,用其中九个位,看自己癖好,此处使用1~10(零位跳过)。
再回到逻辑中。接下来就是一个循环遍历数独中每个元素。
进入for循环内。先取横纵坐标,记为 x,y。然后判断是否为 “.”,即判断是否未存入数字。然后就是转 char 为 数字,因为是 1~9 所以 byte 够用(算法主打就是能省就省)。
接下来就是三个判断,这也是关键。
整体上来说就是判断三个数组中是否已存入某一个数字,未存入就存入,已存入就返回false。
以九宫格验证为例:
第一行 获取此时九宫格的序号。
第三行(二行为空行)
此时 num 为 当前数独内数字,block[tt] 为此时九宫格的存储状态,block [tt] >> num 为此数字向右移num位。
举例:如果此九宫格内存存入过 1,5,7。 则此时 int 类型为 1010_0010 前的零省略.
此例右移 num 位,如果num为5,则此时 int 类型为0000_0101.
然后对 1 进行 & (AND 运算)。AND运算同为1则为1,否则为0。此时举例 int 类型变为0000_0001。然后跟 1 对比,相等,即 num 已经存过。返回false。
第四行 同理 先让1 左移 num 位,然后做 | 运算(OR 为两个数的同一位,有一个 1 就为 1 )。再存入此位置。
最后等循环结束,如果都没事就返回 true。
