当前位置: 首页 > news >正文

LeetCode 36. 有效的数独 - 解题思路与实现详解

LeetCode 36. 有效的数独 - 解题思路与实现详解

题目描述

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可:

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 空白格用 ‘.’ 表示。

解题思路分析

1. 问题理解

数独验证的核心是检查三个维度:

  • 行检查:每一行中的数字1-9不能重复
  • 列检查:每一列中的数字1-9不能重复
  • 3x3宫格检查:每个3x3的小宫格中数字1-9不能重复

2. 关键思考点

2.1 如何处理空白格(‘.’)

空白格用’.'表示,在验证时需要考虑:

  • 集合去重时会自动忽略’.’
  • 需要正确计算有效数字的数量
2.2 3x3宫格的遍历

如何正确遍历9个3x3宫格是关键:

  • 每个宫格的起始位置:(0,0), (0,3), (0,6), (3,0), (3,3), (3,6), (6,0), (6,3), (6,6)
  • 使用双重循环:for x in range(0, 9, 3): for y in range(0, 9, 3)
2.3 列数据的提取

Python中不能直接用board[:][y]获取列,需要使用列表推导式:

column_y = [row[y] for row in board]

代码实现

方法一:集合验证法

class Solution:def isValidSudoku(self, board: list[list[str]]) -> bool:# 检查3x3宫格for x in range(0, 9, 3):for y in range(0, 9, 3):# 提取当前3x3宫格的所有元素grids = [board[x][y], board[x][y+1], board[x][y+2],board[x+1][y], board[x+1][y+1], board[x+1][y+2],board[x+2][y], board[x+2][y+1], board[x+2][y+2]]# 验证:去重后的数字个数 + 空白格个数 = 9if (len(set(grids)) + grids.count('.')) - 1 != 9:return False# 检查每一行for x in range(9):if (len(set(board[x])) + board[x].count('.')) - 1 != 9:return False# 检查每一列for y in range(9):column_y = [row[y] for row in board]if (len(set(column_y)) + column_y.count('.')) - 1 != 9:return Falsereturn True

方法二:哈希表优化法

class Solution:def isValidSudoku(self, board: list[list[str]]) -> bool:# 使用哈希表记录每行、每列、每个宫格中数字的出现情况rows = [set() for _ in range(9)]cols = [set() for _ in range(9)]boxes = [set() for _ in range(9)]for i in range(9):for j in range(9):num = board[i][j]if num == '.':continue# 检查行if num in rows[i]:return Falserows[i].add(num)# 检查列if num in cols[j]:return Falsecols[j].add(num)# 检查3x3宫格box_index = (i // 3) * 3 + j // 3if num in boxes[box_index]:return Falseboxes[box_index].add(num)return True

关键知识点

1. Python集合操作

# 集合去重
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_numbers = set(numbers)  # {1, 2, 3, 4, 5}# 集合长度
len(unique_numbers)  # 5

2. 列表推导式

# 提取矩阵的列
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
column_0 = [row[0] for row in matrix]  # [1, 4, 7]
column_1 = [row[1] for row in matrix]  # [2, 5, 8]

3. 3x3宫格索引计算

# 计算(i,j)位置属于哪个3x3宫格
box_index = (i // 3) * 3 + j // 3# 宫格编号对应关系:
# 0 1 2
# 3 4 5  
# 6 7 8

解题过程中的常见错误

1. 错误理解集合去重

# 错误示例
grids = ['.', '1', '2', '.', '3', '4', '5', '6', '7']
unique_count = len(set(grids))  # 8 (包含了'.')
# 正确做法
valid_count = len(set(grids)) + grids.count('.') - 1  # 7

2. 错误的列提取方式

# 错误示例
board = [[1,2,3], [4,5,6], [7,8,9]]
column = board[:][0]  # 这样不会得到第一列# 正确做法
column = [row[0] for row in board]  # [1, 4, 7]

3. 3x3宫格遍历错误

# 错误示例:没有在循环内重新计算grids
grids = [board[0][0], board[0][1], ...]  # 只计算了一次
for x in range(0, 9, 3):for y in range(0, 9, 3):# 应该在这里重新计算grids

复杂度分析

时间复杂度

  • 方法一:O(n²),其中n=9,需要遍历整个数独板
  • 方法二:O(n²),但实际运行更快,因为使用哈希表查找

空间复杂度

  • 方法一:O(1),只使用常数空间
  • 方法二:O(n),需要存储行、列、宫格的哈希表

测试用例

# 测试用例1:有效数独
board1 = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]
]
# 预期结果:True# 测试用例2:无效数独(第一行有重复)
board2 = [["8","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]
]
# 预期结果:False

总结

这道题的核心在于:

  1. 理解数独规则:行、列、3x3宫格都不能有重复数字
  2. 正确处理空白格:'.'不影响验证,但需要正确计算
  3. 掌握Python语法:集合操作、列表推导式、矩阵操作
  4. 注意边界条件:确保所有情况都被正确验证

通过这道题,我学会了:

  • 如何验证矩阵的多个维度
  • 如何处理特殊字符(如’.')
  • 如何正确提取矩阵的行和列
  • 如何使用集合进行去重验证

这是一道很好的练习Python基础语法和逻辑思维的题目!
更新日期2025年8月31日

http://www.dtcms.com/a/360607.html

相关文章:

  • arnold图像加密(猫脸变换)
  • AIGC应用与实践 - 实验3:使用豆包生成播客
  • 赵玉平《刘备谋略》读书笔记(上部)
  • zookeeper集群是什么技术, 有什么作用
  • 第三阶梯:变动感知——在流沙之上,建造你的灯塔
  • 在开发过程中经常遇到 OOM(内存溢出)问题,如何解决?
  • __getitem__()方法的神奇
  • 【LeetCode修行之路】算法的时间和空间复杂度分析
  • 2000w 的数据量,mysql要进行几次IO操作,为什么
  • GEE 实战:Landsat 5 月度 NDVI 数据插值填补(以 8 月为例)_后附完整代码
  • sting模拟实现
  • 前后端联合实现多个文件上传
  • FastAPI 教程:构建高性能异步 API 服务
  • 石化设备健康管理平台:工业智能化转型的关键使能技术​
  • std::thread详解
  • Spring Boot单体项目整合Nacos
  • C++17 折叠表达式(Fold Expressions)详解
  • ConcurrentHashMap在扩容的过程中又有新的数据写入是怎么处理的
  • 《Bishop PRML》10.1 (3) 理解VAE reconstruction loss
  • Redis 中的 Bitmap 与 Bitfield 及 Java 操作实践
  • python如何下载svg图片
  • 【Proteus仿真】数码管控制系列仿真——单个数码管控制/多数码管控制
  • leetcode 260 只出现一次的数字III
  • 你的数据是如何被保护的?
  • Linux系统的进程管理
  • vue3+vite+ts 发布npm 组件包
  • 查看所有装在c盘软件的方法
  • [知识点记录]SQLite 数据库和MySQL 数据库有什么区别?
  • DuckDB 内嵌分析:ABP 的「本地 OL盘快照」
  • 福彩双色球第2025100期号码推荐