返回
深入剖析 LeetCode 36:验证有效数独的艺术
闲谈
2023-10-01 00:27:38
引言
LeetCode 36 题:“有效数独”,是一道经典算法问题,考验着我们对数独规则的理解和编程能力。本文将带你深入解析这道题目的本质,并用清晰的语言和生动的例子为你展现解决问题的艺术。
理解数独规则
数独是一种基于 9x9 格子的逻辑益智游戏,目标是将 1-9 的数字填充到每个格子中,满足以下规则:
- 每行必须包含 1-9 的所有数字,且每个数字只能出现一次。
- 每列必须包含 1-9 的所有数字,且每个数字只能出现一次。
- 每个 3x3 宫内必须包含 1-9 的所有数字,且每个数字只能出现一次。
算法思路
为了判断一个数独是否有效,我们可以依次检查每一行、每一列和每一个宫,确保它们是否满足规则。具体算法步骤如下:
1. 行检查
遍历数独的每一行,使用一个数组记录出现过的数字。如果任何数字出现超过一次,则数独无效。
2. 列检查
类似地,遍历数独的每一列,使用一个数组记录出现过的数字。如果任何数字出现超过一次,则数独无效。
3. 宫检查
将数独划分为 9 个 3x3 宫。对于每个宫,使用一个数组记录出现过的数字。如果任何数字出现超过一次,则数独无效。
代码实现
public boolean isValidSudoku(char[][] board) {
// 检查行
for (int i = 0; i < 9; i++) {
boolean[] row = new boolean[9];
for (int j = 0; j < 9; j++) {
int num = board[i][j] - '1';
if (num < 0 || num >= 9 || row[num]) {
return false;
}
row[num] = true;
}
}
// 检查列
for (int j = 0; j < 9; j++) {
boolean[] col = new boolean[9];
for (int i = 0; i < 9; i++) {
int num = board[i][j] - '1';
if (num < 0 || num >= 9 || col[num]) {
return false;
}
col[num] = true;
}
}
// 检查宫
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
boolean[] box = new boolean[9];
for (int k = i; k < i + 3; k++) {
for (int l = j; l < j + 3; l++) {
int num = board[k][l] - '1';
if (num < 0 || num >= 9 || box[num]) {
return false;
}
box[num] = true;
}
}
}
}
return true;
}
优化技巧
为了提高算法效率,我们可以引入一些优化技巧:
- 使用 bitset 代替 boolean 数组来记录出现过的数字,可以大大节省空间。
- 对输入的数独进行预处理,将每一行、每一列和每一个宫中已经填入的数字转换为对应的 bitset。
- 并行化宫检查,使用多线程同时检查多个宫。
SEO优化