1. 问题背景与核心需求
数独是一种经典的逻辑游戏,要求在一个9x9的网格中填入数字1-9,满足以下三个条件:
- 每一行必须包含1-9且不重复
- 每一列必须包含1-9且不重复
- 每个3x3的子网格必须包含1-9且不重复
LeetCode第36题要求我们验证一个已经部分填好的数独棋盘是否满足这三个条件。这个问题看似简单,但实际考察了数据结构的选择、边界条件处理以及算法优化能力。
注意:题目明确说明只需要验证已填入的数字是否有效,不需要考虑解的存在性。这是很多初学者容易误解的关键点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解法思路分析与比较
2.1 暴力解法及其局限性
最直观的解法是三次遍历:
- 检查所有行
- 检查所有列
- 检查所有3x3子网格
这种方法时间复杂度为O(3n²),虽然在小规模数据(9x9)上可以接受,但存在明显的重复计算。例如每个元素会被行、列和子网格检查各访问一次。
2.2 优化思路:一次遍历多维度检查
更高效的解法是利用哈希表记录每行、每列和每个子网格已经出现的数字。我们可以在一次遍历中同时更新这三个维度的记录,并在发现重复时立即返回失败。
关键数据结构选择:
- 行记录:长度为9的数组,每个元素是一个集合
- 列记录:同上
- 子网格记录:使用3x3的二维数组,每个元素也是一个集合
2.3 空间优化的可能性
考虑到数独数字范围固定(1-9),我们可以用位掩码替代集合:
- 每个数字对应一个bit位
- 出现时通过位或运算标记
- 检查是否重复只需位与运算
这种方法将空间复杂度从O(n)降低到O(1),因为固定使用9个整数即可。
3. 详细实现与代码解析
3.1 基于集合的标准实现
python复制def isValidSudoku(board):
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [[set() for _ in range(3)] for _ in range(3)]
for i in range(9):
for j in range(9):
num = board[i][j]
