§1
题目描述
判断一个 9×9 数独棋盘是否有效,只需要检查已填数字。
board = 含 5、3、7 等已填数字
输出 = true
§2
思路解析动画文字版
一个格子 (r,c) 的宫编号是 (r//3, c//3),也可以压成 (r//3)*3 + c//3。
扫描 (0,0)=5:遇到数字 5,检查行、列、宫都没见过,再记录进去。
扫描 (0,1)=3:同一行已有 5,但没有 3,所以合法。
跳过空格:空格还没填,不影响合法性。
扫描 (1,3)=1:每个数字同时检查三个维度。
扫描 (2,1)=9:同列不同数字没问题。
宫内检查:宫的范围由 r//3 和 c//3 决定。
负例:行重复:如果 row0 已有 5,再遇到 5 就直接 false。
负例:列重复:负例·列重复:把 (8,0) 填成 5,但第 0 列已有 (0,0)=5 → 同列重复,直接 false。
扫完:整个棋盘扫描结束都没冲突,返回 True。
把约束拆成三个哈希集合,冲突就会非常直观。
边界三连:三种边界先想清楚。
面试官常追问:三个高频追问,答法记牢。
§3
参考代码
class Solution: def isValidSudoku(self, board): rows = [set() for _ in range(9)] cols = [set() for _ in range(9)] boxes = [set() for _ in range(9)] for r in range(9): for c in range(9): x = board[r][c] if x == ".": continue b = (r // 3) * 3 + c // 3 # 宫编号 if x in rows[r] or x in cols[c] or x in boxes[b]: return False rows[r].add(x); cols[c].add(x); boxes[b].add(x) return True看懂代码不等于写得出。盖住上面,自己默写一遍试试。卡在哪一行说不清,就点右下角问小欧。
§4
复杂度
- 时间复杂度:O(1),固定 9×9=81 格,每格 O(1) 检查
- 空间复杂度:O(1),三组常数大小的集合
§5
可套用的代码模板
套路骨架:行/列/宫三组集合,遍历每个已填数字查三维度,任一重复即 false。
Python
class Solution: def valid(self, grid): seen_a = set() seen_b = set() seen_c = set() for item in items: key1, key2, key3 = make_keys(item) if key1 in seen_a or key2 in seen_b or key3 in seen_c: return False seen_a.add(key1) seen_b.add(key2) seen_c.add(key3) return True§6
易错点
✗ 错误写法:把 "." 也放进集合
✓ 正确写法:空格必须跳过
多个空格不是重复数字
✗ 错误写法:宫编号算错
✓ 正确写法:b=(r//3)*3+c//3
同一个 3×3 宫必须落到同一个编号
§
面试追问把动画讲成自己的话
追问核心思路是什么?
遍历每个已填数字,检查它在所在行、列、3×3 宫是否已出现;用三组哈希集合记录,任一处重复即 false。
追问3×3 宫怎么定位?
宫编号 b=(r//3)*3+c//3,把 (r,c) 映射到 0~8;同一个宫的格子算出同一个 b。
追问复杂度?
固定 81 格、每格 O(1) 检查 → 时间 O(1)、空间 O(1)(常数大小集合)。也可用 9 个 int 位掩码代替集合更省。
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
下一题 · 数组 & 哈希 9/20
→最长连续序列
LeetCode 128 · 中等 · 沿着 数组 & 哈希 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
299道动画图解
37节语音讲解
28课数据结构
¥0.27折合 / 天
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
¥99 开通年卡 →
想成体系刷透这类套路?去图解算法专题