LC 36. Valid Sudoku
- Last updated
- Reading time
- 2 min read
The problem
Solution
For this solution, I looped through every value in the 2D array, and stored new, unique numbers in their corresponding rows, columns, and subgrids if possible. If they already existed, I immediately returned false since that would be invalid. Because there are 27 different spaces (9 each of the columns, rows and subgrids) that requires up to 27 to be mapped to check later for duplicates.
The real difficulty with this question is how to properly map the subgrids, the division and Math.floor
below might seem easy, but seeing it for the first time can be tricky. The idea was to reduce each subgrid into a 3 x 3 - indexed map were the keys could identify what square each number was in using different numbers for the rows and columns. Using the rounded division, 0 - 2 reduce down to 0, 3 - 5 reduce to 1, and 6 - 8 reduce to 2. Doing this for all i
rows and j
columns give the 3 x 3 effect that identifies what subgrid I'm in on every iteration.
function isValidSudoku(board: string[][]): boolean {
let map = {}
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] !== '.') {
// Check rows
map[`r${i}`] = map[`r${i}`] ? [...map[`r${i}`], board[i][j]] : [board[i][j]]
if (map[`r${i}`].length !== new Set(map[`r${i}`]).size) {
return false
}
// Check columns
map[`c${j}`] = map[`c${j}`] ? [...map[`c${j}`], board[i][j]] : [board[i][j]]
if (map[`c${j}`].length !== new Set(map[`c${j}`]).size) {
return false
}
// Check subgrids
let square = `s${Math.floor(i / 3)}${Math.floor(j / 3)}`
map[square] = map[square] ? [...map[square], board[i][j]] : [board[i][j]]
if (map[square].length !== new Set(map[square]).size) {
return false
}
}
}
}
return true
}