题目描述
思路解析动画文字版
记牢这套配置:行集合、列集合、宫集合各 9 个。每个数字要同时过三关,过了就登记进三处,撞了就立刻出局。
开始扫描前:行、列、宫三套集合全是空的,已登记 0 个数字。指针从左上角第一格出发。
指针走到第 0 行第 0 列,这格是 5。去查它的第 0 行、第 0 列、第 0 号宫——三套集合里现在都没有 5,三关都过。
把 5 同时记进「第 0 行」「第 0 列」「第 0 号宫」三个集合,这格通过(变蓝)。已登记 1 个数字,继续往后扫。
指针走到第 0 行第 1 列,这格是 3。去查它的第 0 行、第 1 列、第 0 号宫——三套集合里现在都没有 3,三关都过。
把 3 同时记进「第 0 行」「第 1 列」「第 0 号宫」三个集合,这格通过(变蓝)。已登记 2 个数字,继续往后扫。
指针走到第 0 行第 4 列,这格是 7。去查它的第 0 行、第 4 列、第 1 号宫——三套集合里现在都没有 7,三关都过。
把 7 同时记进「第 0 行」「第 4 列」「第 1 号宫」三个集合,这格通过(变蓝)。已登记 3 个数字,继续往后扫。
指针走到第 1 行第 0 列,这格是 6。去查它的第 1 行、第 0 列、第 0 号宫——三套集合里现在都没有 6,三关都过。
把 6 同时记进「第 1 行」「第 0 列」「第 0 号宫」三个集合,这格通过(变蓝)。已登记 4 个数字,继续往后扫。
指针走到第 1 行第 3 列,这格是 1。去查它的第 1 行、第 3 列、第 1 号宫——三套集合里现在都没有 1,三关都过。
把 1 同时记进「第 1 行」「第 3 列」「第 1 号宫」三个集合,这格通过(变蓝)。已登记 5 个数字,继续往后扫。
指针走到第 1 行第 4 列,这格是 9。去查它的第 1 行、第 4 列、第 1 号宫——三套集合里现在都没有 9,三关都过。
把 9 同时记进「第 1 行」「第 4 列」「第 1 号宫」三个集合,这格通过(变蓝)。已登记 6 个数字,继续往后扫。
指针走到第 1 行第 5 列,这格是 5。去查它的第 1 行、第 5 列、第 1 号宫——三套集合里现在都没有 5,三关都过。
把 5 同时记进「第 1 行」「第 5 列」「第 1 号宫」三个集合,这格通过(变蓝)。已登记 7 个数字,继续往后扫。
指针走到第 2 行第 1 列,这格是 9。去查它的第 2 行、第 1 列、第 0 号宫——三套集合里现在都没有 9,三关都过。
把 9 同时记进「第 2 行」「第 1 列」「第 0 号宫」三个集合,这格通过(变蓝)。已登记 8 个数字,继续往后扫。
指针走到第 2 行第 2 列,这格是 8。去查它的第 2 行、第 2 列、第 0 号宫——三套集合里现在都没有 8,三关都过。
把 8 同时记进「第 2 行」「第 2 列」「第 0 号宫」三个集合,这格通过(变蓝)。已登记 9 个数字,继续往后扫。
指针走到第 2 行第 7 列,这格是 6。去查它的第 2 行、第 7 列、第 2 号宫——三套集合里现在都没有 6,三关都过。
把 6 同时记进「第 2 行」「第 7 列」「第 2 号宫」三个集合,这格通过(变蓝)。已登记 10 个数字,继续往后扫。
指针走到第 3 行第 0 列,这格是 8。去查它的第 3 行、第 0 列、第 3 号宫——三套集合里现在都没有 8,三关都过。
把 8 同时记进「第 3 行」「第 0 列」「第 3 号宫」三个集合,这格通过(变蓝)。已登记 11 个数字,继续往后扫。
看个反例:假设第 0 行第 2 列也想填 5(标红那格)。可第 0 行已经登记过 5(左边高亮那格),一查集合就撞上——这种情况立刻判定无效。
本题这张盘没有任何一处撞车,全程三关都过。继续扫完剩下的格子也都通过,最终判定:有效。
三个高频追问:27 个集合的来源、判有效≠求解、一次遍历同时管三关。
参考代码
def isValidSudoku(board): rows = [set() for _ in range(9)] # 9 行各一个集合 cols = [set() for _ in range(9)] # 9 列各一个集合 boxes = [set() for _ in range(9)] # 9 个 3x3 宫各一个 for i in range(9): for j in range(9): d = board[i][j] if d == '.': # 空格跳过 continue b = (i // 3) * 3 + j // 3 # 宫编号 0-8 if d in rows[i] or d in cols[j] or d in boxes[b]: return False # 任一处撞 → 无效 rows[i].add(d); cols[j].add(d); boxes[b].add(d) return True复杂度
- 时间:O(1),盘面固定 9×9,至多看 81 格、每格查/记 3 个集合,是常数次操作
- 空间:O(1),27 个集合,每个最多装 9 个数字,总量固定,与输入规模无关
易错点
面试追问把动画讲成自己的话
追问为什么是 27 个集合?
追问需要把数独解出来才能判断有效吗?
追问能不能用一次遍历同时判三关,而不是扫三遍?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最长连续序列
LeetCode 128 · 中等 · 沿着 数组 & 哈希 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题