这道题是官方编辑的初级算法中数组部分的一个题目,是一道中等难度的题。首先还是先看一下题目描述吧。
题目地址:有效的数独
数独大家都很熟悉,简单来讲这个题目就是要让我们写一个程序判断这个数独是不是合法的。但是题目并不要求我们判断数独是不是可解的,而且数独是一个9宫格。
解答方法
拿到这题第一反应还是暴力法,直接遍历三次,一次判断每行是否合法,一次判断每列是否合法,一次判断每个33的格子是否合法。但是实际上,这三个判断并不需要遍历数组三次,只需要一次就够了。另外,遍历每一个33的格子这个有点难度,反正我做的时候是一直没有想到,直到看了答案才知道怎么做。
为了判断每行内列每个格子是否合法,就是判断是否有重复元素,那么我们首先想到的肯定是使用哈希表。这个题使用哈希表是可以的,但是实际上,因为这题只涉及到9个元素,我们直接使用数组就可以了。为行,列,和3*3的格子各初始化一个二维数组,存放每行每列每个格子里面各元素出现次数,有次数大于1的就直接返回False。
在遍历时,我们需要知道当前遍历到的是哪一行哪一列以及哪一个格子。在哪行哪列很好判断,直接就是当前元素下标。但是如上图所示,我们要怎么知道现在处于哪一个格子呢,我们可以采用这个公式来判断,使用i,j分别代表行和列的下标,那么当前所在格子应该是(i/3)*3+j/3,其中/是取商的操作。这个公式的意思就是将行和列的每三步当做一个格子的一步,行或者列每走三步,那么格子的下标就走一步。解决了格子的编号问题,这个题的代码就简单了。
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
row = [[0]*9 for i in range(9)]
col = [[0]*9 for i in range(9)]
box = [[0]*9 for i in range(9)]
for i in range(9):
for j in range(9):
num = board[i][j]
box_index = (i//3)*3 + j//3
if num != '.':
num = int(num)-1
row[i][num] = row[i][num] + 1
col[j][num] = col[j][num] + 1
box[box_index][num] = box[box_index][num]+1
if row[i][num]>1 or col[j][num]>1 or box[box_index][num]>1:
return False
return True
这个题总体来说对我还是有些难度的,最主要的是如何去判断3*3格子的合法性困扰了我很久,直到看到答案才知道原来是这样。