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 digits1-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.
Solution in Python:
To determine if a 9×9 Sudoku board is valid, we need to check three main conditions:
- 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×3 sub-boxes of the grid must contain the digits 1-9 without repetition.
We can achieve this by iterating through the board and using sets to keep track of the digits we’ve seen in each row, column, and sub-box. If we encounter a duplicate digit in any of these, the board is invalid.
Python
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
# Initialize sets to keep track of seen numbers in rows, columns, and sub-boxes
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [set() for _ in range(9)]
for i in range(9):
for j in range(9):
num = board[i][j]
if num == '.':
continue
# Calculate the index for the 3x3 sub-box
box_index = (i // 3) * 3 + (j // 3)
# Check if the number is already in the row, column or box
if num in rows[i]:
return False
if num in cols[j]:
return False
if num in boxes[box_index]:
return False
# Add the number to the respective sets
rows[i].add(num)
cols[j].add(num)
boxes[box_index].add(num)
# If no conflicts were found, the board is valid
return True
Detailed Explanation:
- Initialize Sets:
- We create three lists of sets:
rows
,cols
, andboxes
. Each list contains 9 sets (one for each row, column, and 3×3 sub-box).
- We create three lists of sets:
- Iterate Through the Board:
- We use nested loops to iterate over each cell in the 9×9 board.
- Skip Empty Cells:
- If the cell contains ‘.’, we skip it because it does not need to be validated.
- Calculate Box Index:
- We calculate the index for the 3×3 sub-box using the formula
(i // 3) * 3 + (j // 3)
. This ensures that cells in the same 3×3 sub-box get the same index.
- We calculate the index for the 3×3 sub-box using the formula
- Check for Duplicates:
- We check if the number already exists in the corresponding row, column, or box set.
- If it does, we return
False
immediately as the board is invalid.
- Add Number to Sets:
- If the number is not a duplicate, we add it to the respective sets for the row, column, and box.
- Return True:
- If we finish checking all cells without finding any duplicates, we return
True
, indicating the board is valid.
- If we finish checking all cells without finding any duplicates, we return
Solution in Javascript:
JavaScript
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
// Initialize sets to keep track of seen numbers in rows, columns, and sub-boxes
const rows = Array.from({ length: 9 }, () => new Set());
const cols = Array.from({ length: 9 }, () => new Set());
const boxes = Array.from({ length: 9 }, () => new Set());
// Iterate over each cell in the 9x9 board
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const num = board[i][j];
// Skip empty cells
if (num === '.') continue;
// Calculate the index for the 3x3 sub-box
const boxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3);
// Check if the number is already in the row, column or box
if (rows[i].has(num)) return false;
if (cols[j].has(num)) return false;
if (boxes[boxIndex].has(num)) return false;
// Add the number to the respective sets
rows[i].add(num);
cols[j].add(num);
boxes[boxIndex].add(num);
}
}
// If no conflicts were found, the board is valid
return true;
};
Solution in Java:
Java
class Solution {
public boolean isValidSudoku(char[][] board) {
// Initialize sets to keep track of seen numbers in rows, columns, and sub-boxes
Set<Character>[] rows = new HashSet[9];
Set<Character>[] cols = new HashSet[9];
Set<Character>[] boxes = new HashSet[9];
// Instantiate the sets
for (int i = 0; i < 9; i++) {
rows[i] = new HashSet<>();
cols[i] = new HashSet<>();
boxes[i] = new HashSet<>();
}
// Iterate over each cell in the 9x9 board
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char num = board[i][j];
// Skip empty cells
if (num == '.') continue;
// Calculate the index for the 3x3 sub-box
int boxIndex = (i / 3) * 3 + (j / 3);
// Check if the number is already in the row, column or box
if (rows[i].contains(num)) return false;
if (cols[j].contains(num)) return false;
if (boxes[boxIndex].contains(num)) return false;
// Add the number to the respective sets
rows[i].add(num);
cols[j].add(num);
boxes[boxIndex].add(num);
}
}
// If no conflicts were found, the board is valid
return true;
}
}
Solution in C#:
C#
public class Solution {
public bool IsValidSudoku(char[][] board) {
// Initialize sets to keep track of seen numbers in rows, columns, and sub-boxes
HashSet<char>[] rows = new HashSet<char>[9];
HashSet<char>[] cols = new HashSet<char>[9];
HashSet<char>[] boxes = new HashSet<char>[9];
// Instantiate the sets
for (int i = 0; i < 9; i++) {
rows[i] = new HashSet<char>();
cols[i] = new HashSet<char>();
boxes[i] = new HashSet<char>();
}
// Iterate over each cell in the 9x9 board
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char num = board[i][j];
// Skip empty cells
if (num == '.') continue;
// Calculate the index for the 3x3 sub-box
int boxIndex = (i / 3) * 3 + (j / 3);
// Check if the number is already in the row, column or box
if (rows[i].Contains(num)) return false;
if (cols[j].Contains(num)) return false;
if (boxes[boxIndex].Contains(num)) return false;
// Add the number to the respective sets
rows[i].Add(num);
cols[j].Add(num);
boxes[boxIndex].Add(num);
}
}
// If no conflicts were found, the board is valid
return true;
}
}