Valid Sudoku

Updated on 01 July, 2025
Valid Sudoku header image

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:

  1. Each row contains the digits 1-9 without repetition of any number.
  2. Each column also must have the digits 1-9 without any number appearing more than once.
  3. Each of the nine 3 x 3 sub-boxes within the larger grid should similarly contain the digits 1-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 digit 1-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:

  1. 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.
  2. Sub-Boxes:

    • The 9 x 9 board can be divided into nine 3 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.

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
cpp
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, and boxMasks 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, and boxMasks:

    • 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 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.

java
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, and boxData 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.

c
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, and subgridMarks 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.

js
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.

python
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.

Comments

No comments yet.