36、有效的数独
js
;(function () {
/**
* 36. 有效的数独
* 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
* 数字 1-9 在每一行只能出现一次。
* 数字 1-9 在每一列只能出现一次。
* 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
* 注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 '.' 表示。
* ------------------------------------------------
* 输入:board =
[["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
*
* 输入:board =
[["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
* ----------------------------------------
* 提示:
board.length == 9
board[i].length == 9
board[i][j] 是一位数字(1-9)或者 '.'
行:row
列:column
*/
function isValidSudoku(board: string[][]): boolean {
// 方法一
// let bool = true
// // 临时数组:保存三个来源的数组数据(1. 原 board 的每行;2. 原 board 的每列;3.原 board 的 3x3 宫内数据组成的数组)
// let tempBoards: string[][] = [];
// // 1. 插入每行数据
// board.forEach(x => {
// tempBoards.push([...x])
// })
// // 2. 插入每列数据
// // 旋转矩阵
// let rotateBoard = Array.from(board);
// let length = rotateBoard.length;
// for (let i = 0; i < length; ++i) {
// for (let j = i + 1; j < length; ++j) {
// let temp = rotateBoard[i][j];
// rotateBoard[i][j] = rotateBoard[j][i];
// rotateBoard[j][i] = temp;
// }
// }
// rotateBoard.forEach(x => {
// tempBoards.push(x)
// })
// // 3. 插入3x3 宫内数据
// let temp3x3BoardBase: number[][] = [];
// let temp3x3Board: string[][] = new Array(9).fill(0).map(() => new Array());
// board.forEach((arr, k) => {
// arr.forEach((item, index) => {
// // 找到 3x3 的基点(即每个九宫格的原点位置)
// k % 3 === 0 && index % 3 === 0 ? temp3x3BoardBase.push([k, index]) : null;
// })
// })
// temp3x3BoardBase.forEach((x, k) => {
// let r = x[0];
// let c = x[1];
// for(let i = r; i < r + 3; i++) {
// for(let j = c; j < c + 3; j++) {
// temp3x3Board[k].push(board[i][j])
// }
// }
// })
// temp3x3Board.forEach(x => {
// tempBoards.push(x)
// })
// // 核心: 判断数独
// tempBoards.forEach(x => {
// let nums = x.filter(item => item !== '.');
// let len = nums.length;
// let numsAfterSet = [...Array.from(new Set(nums))];
// let newLen = numsAfterSet.length;
// // 相等,说明没有重复的数字
// len === newLen ? null : bool = false;
// })
// return bool
// 方法二:官方方法
const rows = new Array(9).fill(0).map(() => new Array(9).fill(0))
const columns = new Array(9).fill(0).map(() => new Array(9).fill(0))
const subboxes = new Array(3)
.fill(0)
.map(() => new Array(3).fill(0).map(() => new Array(9).fill(0)))
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const c = board[i][j]
if (c !== '.') {
const index = +c - 1
rows[i][index]++
columns[j][index]++
subboxes[Math.floor(i / 3)][Math.floor(j / 3)][index]++
if (
rows[i][index] > 1 ||
columns[j][index] > 1 ||
subboxes[Math.floor(i / 3)][Math.floor(j / 3)][index] > 1
) {
return false
}
}
}
}
return true
// 方法三
// todo...
}
const boardArr = [
['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']
]
const boardArr2 = [
['7', '.', '.', '.', '4', '.', '.', '.', '.'],
['.', '.', '.', '8', '6', '5', '.', '.', '.'],
['.', '1', '.', '2', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '9', '.', '.', '.'],
['.', '.', '.', '.', '5', '.', '5', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '2', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.']
]
// console.log(isValidSudoku(boardArr))
console.log(isValidSudoku(boardArr2))
})()