跳到主要内容

valid-sudoku

https://leetcode.com/problems/valid-sudoku/

function isValidSudoku(board: string[][]): boolean {
// 创建三个集合来存储行、列和九宫格的数字
const rows = Array.from({ length: 9 }, () => new Set());
const cols = Array.from({ length: 9 }, () => new Set());
const boxes = Array.from({ length: 9 }, () => new Set());

// 遍历整个数独板
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const num = board[i][j];
if (num === ".") continue;

// 计算九宫格索引
const boxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3);

// 检查数字是否已经在行、列或九宫格中存在
if (rows[i].has(num) || cols[j].has(num) || boxes[boxIndex].has(num)) {
return false;
}

// 将数字添加到对应的集合中
rows[i].add(num);
cols[j].add(num);
boxes[boxIndex].add(num);
}
}

return true;
}

复杂度分析

  • 时间复杂度: O(1),因为数独板的大小是固定的 9x9
  • 空间复杂度: O(1),使用了固定大小的集合来存储数字

测试用例

// 测试用例 1:有效的数独
console.log(
isValidSudoku([
["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"],
]),
); // expect: true

// 测试用例 2:无效的数独(行重复)
console.log(
isValidSudoku([
["5", "3", ".", ".", "7", ".", "5", ".", "."],
["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"],
]),
); // expect: false

// 测试用例 3:无效的数独(列重复)
console.log(
isValidSudoku([
["5", "3", ".", ".", "7", ".", ".", ".", "."],
["5", ".", ".", "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"],
]),
); // expect: false

// 测试用例 4:无效的数独(九宫格重复)
console.log(
isValidSudoku([
["5", "3", ".", ".", "7", ".", ".", ".", "."],
["6", "5", ".", "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"],
]),
); // expect: false

// 测试用例 5:空数独
console.log(
isValidSudoku([
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", ".", "."],
]),
); // expect: true

数组和哈希概念使用说明

  • 使用二维数组 board 表示数独板
  • 使用 Set 数据结构(哈希集合)来追踪每行、每列和每个九宫格中出现的数字
  • 通过数组索引计算来确定九宫格的位置:boxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3)
  • 利用 Sethas()add() 方法来检查和记录数字的出现情况