36. Valid Sudoku

Medium

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:

  1. Each row must contain the digits 1-9 without repetition.
  2. Each column must contain the digits 1-9 without repetition.
  3. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition.

Note:

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.
Jump to Solution: Python Java C++ JavaScript C#

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

Solution Explanation

This solution uses hash sets to track numbers seen in each row, column, and 3x3 box. Here's how it works:

Key points: