Valid Sudoku
Problem Statement
Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
- Each row must contain the digits
1-9without repetition. - Each column must contain the digits
1-9without repetition. - Each of the nine
3 x 3sub-boxes of the grid must contain the digits1-9without repetition.
Note: A Sudoku board (partially filled) could be valid but is not necessarily solvable. Only the filled cells need to be validated.
Example
Input:
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"]]
Output: true
Approach: Single Hash Set with String Encoding
Instead of maintaining 27 different sets (9 for rows, 9 for columns, 9 for boxes), we can use a single Hash Set to track all constraints simultaneously. We do this by encoding the location and the value into a unique string format.
For example, if we see the number 5 at row 0 and column 2, we generate three unique strings:
'r05'(indicates 5 is in row 0)'c25'(indicates 5 is in column 2)'b05'(indicates 5 is in box 0)
The main trick is determining which sub-box a specific cell (i, j) belongs to. We can uniquely identify the 9 sub-boxes (indexed 0 to 8) using the formula:
boxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3)
- Initialize a single Hash Set called
set. - Iterate through every cell in the grid.
- If the cell is empty (
"."), skip it. - For a filled cell, compute its
boxIndexand generate the three encoded strings for its row, column, and box. - Check if any of these strings already exist in the
set.- If they do, we found a duplicate! Return
false. - If they donβt, add all three strings to the
set.
- If they do, we found a duplicate! Return
- If the loop finishes without violations, return
true.
Solution
/**
* @param {character[][]} board
* @return {boolean}
*/
function isValidSudoku (board) {
const set = new Set();
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
const val = board[i][j];
if (val !== '.') {
const rowIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3);
if (set.has('r' + i + val) || set.has('c' + j + val) || set.has('b' + rowIndex + val)) {
return false;
} else {
set.add('r' + i + val);
set.add('c' + j + val);
set.add('b' + rowIndex + val);
}
}
}
}
return true;
};
Complexity Analysis
- Time Complexity: (or strictly ). We perform exactly 81 iterations since the board is fixed at . Set lookups and insertions take constant time .
- Space Complexity: . The Hash Set stores at most strings. Since this is bounded by a constant, the space requirement is constant.