Problem Description
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-9 without repetition.
- Each column must contain the digits 1-9 without repetition.
- Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition.
Note:
- A Sudoku board (partially filled) could be valid but is not necessarily solvable.
- Only the filled cells need to be validated according to the mentioned rules.
Examples
Example 1: 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 Example 2: Input: 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"]] Output: false Explanation: Same as Example 1, except with the 5 in the top left corner being modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Python Solution
def isValidSudoku(board: List[List[str]]) -> bool:
# Initialize sets to store seen numbers
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [set() for _ in range(9)]
# Check each cell
for i in range(9):
for j in range(9):
if board[i][j] == ".":
continue
num = board[i][j]
box_idx = (i // 3) * 3 + j // 3
# Check if number already exists in row, column, or box
if (num in rows[i] or
num in cols[j] or
num in boxes[box_idx]):
return False
# Add number to sets
rows[i].add(num)
cols[j].add(num)
boxes[box_idx].add(num)
return True
Java Solution
class Solution {
public boolean isValidSudoku(char[][] board) {
// Initialize HashSets to store seen numbers
HashSet seen = new HashSet<>();
// Check each cell
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
char number = board[i][j];
// Try to add all 3 formats. If any fails, board is invalid
if (!seen.add(number + " in row " + i) ||
!seen.add(number + " in column " + j) ||
!seen.add(number + " in box " + i/3 + "-" + j/3))
return false;
}
}
}
return true;
}
}
C++ Solution
class Solution {
public:
bool isValidSudoku(vector>& board) {
vector> rows(9);
vector> cols(9);
vector> boxes(9);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == '.') continue;
char num = board[i][j];
int box_idx = (i / 3) * 3 + j / 3;
if (rows[i].count(num) ||
cols[j].count(num) ||
boxes[box_idx].count(num)) {
return false;
}
rows[i].insert(num);
cols[j].insert(num);
boxes[box_idx].insert(num);
}
}
return true;
}
};
JavaScript Solution
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
// Initialize sets to store seen numbers
const rows = Array(9).fill().map(() => new Set());
const cols = Array(9).fill().map(() => new Set());
const boxes = Array(9).fill().map(() => new Set());
// Check each cell
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (board[i][j] === '.') continue;
const num = board[i][j];
const boxIdx = Math.floor(i / 3) * 3 + Math.floor(j / 3);
// Check if number already exists
if (rows[i].has(num) ||
cols[j].has(num) ||
boxes[boxIdx].has(num)) {
return false;
}
// Add number to sets
rows[i].add(num);
cols[j].add(num);
boxes[boxIdx].add(num);
}
}
return true;
};
C# Solution
public class Solution {
public bool IsValidSudoku(char[][] board) {
// Initialize HashSets to store seen numbers
HashSet seen = new HashSet();
// Check each cell
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
char number = board[i][j];
// Try to add all 3 formats. If any fails, board is invalid
if (!seen.Add(number + " in row " + i) ||
!seen.Add(number + " in column " + j) ||
!seen.Add(number + " in box " + i/3 + "-" + j/3))
return false;
}
}
}
return true;
}
}
Complexity Analysis
- Time Complexity: O(1) since we're always iterating through 81 cells
- Space Complexity: O(1) since we store at most 9 * 9 * 3 elements
Solution Explanation
This solution uses hash sets to track numbers seen in each row, column, and 3x3 box. Here's how it works:
- Initialize separate sets for each row, column, and 3x3 box
- Iterate through each cell in the board:
- Skip empty cells ('.')
- Calculate which 3x3 box the current cell belongs to
- Check if the number already exists in the current row, column, or box
- If it exists, return false (invalid Sudoku)
- If not, add the number to the respective sets
- If we complete the iteration without finding duplicates, return true
Key points:
- We only need to check filled cells
- The box index can be calculated using integer division
- Using sets ensures O(1) lookup time
- We don't need to check if numbers are 1-9 as per problem constraints