
Problem Statement
To determine if a 9 x 9
Sudoku board is valid, it's essential to verify the filled cells against specific validation rules. The board, which may not be completely solved, adheres to the rules if:
- Each row contains the digits
1-9
without repetition of any number. - Each column also must have the digits
1-9
without any number appearing more than once. - Each of the nine
3 x 3
sub-boxes within the larger grid should similarly contain the digits1-9
with no duplicates.
A partially filled board may still be considered valid if all placed numbers align with these expectations. It is important to note that a valid board does not guarantee that the Sudoku puzzle is solvable; our only concern is the validity of the placements made.
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.
Constraints
board.length == 9
board[i].length == 9
board[i][j]
is a digit1-9
or'.'
.
Approach and Intuition
The solution to validate a Sudoku board is fundamentally about checking that there are no violations of the rules mentioned in the row, column, or sub-box constraints. To interpret the solution, let's break down the approach:
Rows and Columns:
- Traverse each row and column.
- For each filled cell, check if the value appears elsewhere in the same row or column using a set for tracking.
- If a duplicate is found, the board is invalid.
Sub-Boxes:
- The
9 x 9
board can be divided into nine3 x 3
sub-boxes. - For validation, iterate through each sub-box and store the values of filled cells.
- Use a set for each sub-box to monitor for any duplications.
- The
Note Based on Examples:
- From the examples provided, a valid board (Example 1) shows no duplications in rows, columns, or sub-boxes.
- An invalid example (Example 2) illustrates a violation where two '8's appear within the same sub-box, rendering it invalid.
These checks can be implemented using dictionaries or sets to efficiently record and verify the presence of numbers in rows, columns, and sub-boxes as the matrix is traversed. This method ensures that as soon as a duplication is detected in any of the required checks, the function can promptly return false
, indicating that the board is invalid. If the end of the function is reached without detecting any violations, the board is valid and true
is returned.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
bool checkSudoku(vector<vector<char>>& grid) {
const int SIZE = 9;
int rowMasks[SIZE] = {0};
int colMasks[SIZE] = {0};
int boxMasks[SIZE] = {0};
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (grid[i][j] == '.') {
continue;
}
int value = grid[i][j] - '0';
int bit = 1 << (value - 1);
if ((rowMasks[i] & bit) > 0) {
return false;
}
rowMasks[i] |= bit;
if ((colMasks[j] & bit) > 0) {
return false;
}
colMasks[j] |= bit;
int boxIndex = (i / 3) * 3 + j / 3;
if ((boxMasks[boxIndex] & bit) > 0) {
return false;
}
boxMasks[boxIndex] |= bit;
}
}
return true;
}
};
The provided C++ code defines a method to verify if a given 9x9 grid is a valid Sudoku configuration. Understood through this code are the following key operations that ensure Sudoku's validity rules which state that each row, column, and 3x3 subgrid must contain unique numbers from 1 to 9:
Three arrays named
rowMasks
,colMasks
, andboxMasks
are initialized to keep track of the numbers found in each row, column, and 3x3 box respectively using bitwise operations. Each index in these arrays corresponds to a row, column, or box.The method iterates through each grid position. If it finds a non-empty cell (denoted by values other than '.'), it calculates a bit representation of the number by shifting the integer representation of the number to the left.
For the current number in the grid, it checks whether the corresponding bit is already set in
rowMasks
,colMasks
, andboxMasks
:- If the bit is already set, it indicates the number has been encountered before in the current row, column, or box, hence it returns
false
, invalidating the Sudoku grid. - If the bit is not set, it updates the bit masks to include this number using a bitwise OR operation.
- If the bit is already set, it indicates the number has been encountered before in the current row, column, or box, hence it returns
If the entire grid is processed without conflicts, the method returns
true
, verifying that the grid is indeed a valid Sudoku layout.
Overall, this method efficiently enforces the unique number constraint in Sudoku puzzles using bitwise manipulation for checking and setting the occurrences of numbers in rows, columns, and boxes.
class Solution {
public boolean checkSudokuValidity(char[][] sudokuGrid) {
int gridSize = 9;
int[] rowData = new int[gridSize];
int[] columnData = new int[gridSize];
int[] boxData = new int[gridSize];
for (int row = 0; row < gridSize; row++) {
for (int col = 0; col < gridSize; col++) {
if (sudokuGrid[row][col] == '.') {
continue;
}
int value = sudokuGrid[row][col] - '0';
int bitmask = 1 << (value - 1);
// Validate the row
if ((rowData[row] & bitmask) > 0) {
return false;
}
rowData[row] |= bitmask;
// Validate the column
if ((columnData[col] & bitmask) > 0) {
return false;
}
columnData[col] |= bitmask;
// Validate the box
int boxIndex = (row / 3) * 3 + col / 3;
if ((boxData[boxIndex] & bitmask) > 0) {
return false;
}
boxData[boxIndex] |= bitmask;
}
}
return true;
}
}
This Java program provides a method to determine if a given 9x9 Sudoku grid is valid. The code uses bitwise operations to efficiently check rows, columns, and 3x3 subgrids (boxes) without utilizing additional space for frequently accessed data.
Here's how the code functions:
- Initializes three arrays
rowData
,columnData
, andboxData
to store information about which numbers have been used in each row, column, and box. - Iterates over each cell in the 9x9 grid. For cells containing numbers (not the placeholder '.'), the code performs the following checks:
- Converts the number in each cell from a character to an integer.
- Uses a bitmask to check whether that number has previously appeared in the current row, column, or box.
- If a repeat is detected in any row, column, or box, the function immediately returns
false
.
- Updates the bitmask for the row, column, and box associated with each number to indicate that the number has been used in those locations.
- If no conflicts are found throughout the grid, the function returns
true
, confirming that the Sudoku puzzle adheres to all rules.
This solution is efficient as it combines the use of bitwise operations with direct index access, ensuring quick checks and updates for Sudoku validity. Through this clever use of bitmasking, the space complexity is kept at O(1), as the storage does not grow with the size of the input but remains constant, providing an optimized solution for the problem.
bool checkSudokuValidity(char** sudokuGrid, int gridSize, int* colSizes) {
int DIM = 9;
// Initialize markers for rows, columns, and sub-grids
unsigned int rowMarks[9] = {0};
unsigned int colMarks[9] = {0};
unsigned int subgridMarks[9] = {0};
for (int i = 0; i < DIM; i++) {
for (int j = 0; j < DIM; j++) {
// Ignore empty spots
if (sudokuGrid[i][j] == '.') {
continue;
}
int number = sudokuGrid[i][j] - '0';
unsigned int bitMask = 1 << (number - 1);
// Check for the number in the current row
if (rowMarks[i] & bitMask) {
return false;
}
rowMarks[i] |= bitMask;
// Check for the number in the current column
if (colMarks[j] & bitMask) {
return false;
}
colMarks[j] |= bitMask;
// Calculate sub-grid index
int subgridIdx = (i / 3) * 3 + j / 3;
if (subgridMarks[subgridIdx] & bitMask) {
return false;
}
subgridMarks[subgridIdx] |= bitMask;
}
}
return true;
}
This summary explains the C function checkSudokuValidity
designed to determine if a given 9x9 Sudoku grid is valid. The function takes three arguments: sudokuGrid
, which is a pointer to a 2D array representing the Sudoku board, gridSize
, indicating the size of the grid (9x9), and colSizes
, an array holding the size of each column.
The function initializes:
DIM
as 9 to represent standard Sudoku dimensions.- Three arrays
rowMarks
,colMarks
, andsubgridMarks
to keep track of which numbers (1-9) have been placed in each row, column, and 3x3 sub-grid, respectively.
The logic proceeds by iterating over each cell in the grid:
- Ignore cells containing '.' as they represent empty spots.
- For each number in a cell, calculate a bitmask. If the number already exists in the current row, column, or sub-grid (checked against respective marks arrays using bitwise AND with the bitmask), return
false
. - Otherwise, update the row, column, and sub-grid marks (using bitwise OR) to indicate that the number is now used.
If no conflicts are found throughout the entire grid, the function returns true
, validating the Sudoku configuration as correct.
var checkSudokuValidity = function (sudokuGrid) {
let gridSize = 9;
let rowTracker = Array(gridSize).fill(0);
let colTracker = Array(gridSize).fill(0);
let boxTracker = Array(gridSize).fill(0);
for (let row = 0; row < gridSize; row++) {
for (let col = 0; col < gridSize; col++) {
if (sudokuGrid[row][col] === ".") continue;
let bit = 1 << (parseInt(sudokuGrid[row][col], 10) - 1);
if (rowTracker[row] & bit) return false;
rowTracker[row] |= bit;
if (colTracker[col] & bit) return false;
colTracker[col] |= bit;
let boxIndex = Math.floor(row / 3) * 3 + Math.floor(col / 3);
if (boxTracker[boxIndex] & bit) return false;
boxTracker[boxIndex] |= bit;
}
}
return true;
};
To solve the problem of determining whether a provided 9x9 grid represents a valid Sudoku configuration, the solution involves implementing the function checkSudokuValidity
in JavaScript. This function adheres to the rules of Sudoku where each row, column, and 3x3 box must contain the digits 1-9 without repetition.
Understand the Implementation:
- Initialize three arrays to track used numbers in rows (
rowTracker
), columns (colTracker
), and boxes (boxTracker
) respectively. - The function loops through each cell of the 9x9 grid. For each cell:
- Skip the iteration if the cell is empty (indicated by ".").
- Calculate a bitmask for the current digit to manage the occurrence marks easily and check for duplicates.
- Check for duplicates in the current row, current column, and the corresponding 3x3 box using bitwise AND operations.
- Update the tracking rows, columns, and boxes using bitwise OR operations to mark the occurrence of the digit.
- If a duplicate is detected, the function returns
false
.
- If no duplicates are found throughout the loops, the function finally returns
true
, indicating the Sudoku is valid.
This method leverages bitwise operators for efficient validity checking and concise management of presence or absence of numbers. The box index calculation partitions the grid dynamically based on the current row and column, acknowledging the 3x3 region requirement of Sudoku.
Utilize this Solution:
Ensure you reference a proper 9x9 Sudoku grid as input. The function checks the grid in a comprehensive yet efficient manner using computational tricks ideal for such validation problems. By understanding this method, you maintain robustness in figuring out grid validity for any Sudoku puzzles you encounter.
class Solution:
def checkSudoku(self, grid: List[List[str]]) -> bool:
size = 9
row_masks = [0] * size
col_masks = [0] * size
box_masks = [0] * size
for i in range(size):
for j in range(size):
if grid[i][j] == ".":
continue
val = int(grid[i][j]) - 1
if row_masks[i] & (1 << val):
return False
row_masks[i] |= 1 << val
if col_masks[j] & (1 << val):
return False
col_masks[j] |= 1 << val
box_index = (i // 3) * 3 + j // 3
if box_masks[box_index] & (1 << val):
return False
box_masks[box_index] |= 1 << val
return True
In the "Valid Sudoku" Python solution, the code checks if a given 9x9 Sudoku board is valid, according to the rules of Sudoku. The solution uses bitwise operations to efficiently track occurrences of numbers in rows, columns, and 3x3 sub-grids. Here's how the algorithm operates:
- A 9-element list is initialized for row_masks, col_masks, and box_masks to keep track of numbers present in each row, column, and box using bit flags.
- The code iterates through each cell in the 9x9 grid. If the cell contains a '.', it skips to the next cell since '.' represents an empty space in Sudoku.
- For each number found in a cell, the code calculates its corresponding bit position value and modifies bitmask for the respective row, column, and box.
- For each element:
- Convert the character to an integer and adjust it to a zero-based index.
- Check the bitmask to determine if the number already exists in the current row, column, or box. If it does, the Sudoku board is immediately deemed invalid, and the function returns
False
. - If the number is not already present, the respective masks are updated to include this number.
- The function concludes by returning
True
, indicating that the board adheres to all Sudoku rules.
This approach avoids the need for nested loops or additional data structures typically used to check conditions in Sudoku, thus optimizing the operation and making it efficient even for complex boards.
No comments yet.