Bird
Raised Fist0
Interview PrepbacktrackinghardAmazonFacebookGoogleSnap

Sudoku Solver

Choose your preparation mode4 modes available
📋
Problem

Imagine you have a partially completed Sudoku puzzle and want a program to fill in the missing numbers correctly, respecting all Sudoku rules.

Given a 9x9 Sudoku board partially filled with digits 1-9 and empty cells represented by '.', fill the board so that every row, every column, and every 3x3 sub-box contains the digits 1 through 9 exactly once. Modify the board in-place.

board is a 9x9 gridEach cell contains a digit '1'-'9' or '.' for emptyThe input board is guaranteed to have a valid solution
Edge cases: Board with only one empty cell → should fill that cell correctlyBoard with multiple empty cells in the same row/column/box → must respect all constraintsBoard with minimal clues (17 clues) → still solvable by backtracking
</>
IDE
def solveSudoku(board: list[list[str]]) -> None:public void solveSudoku(char[][] board)void solveSudoku(vector<vector<char>>& board)function solveSudoku(board)
def solveSudoku(board):
    # Write your solution here
    pass
class Solution {
    public void solveSudoku(char[][] board) {
        // Write your solution here
    }
}
#include <vector>
using namespace std;

void solveSudoku(vector<vector<char>>& board) {
    // Write your solution here
}
function solveSudoku(board) {
    // Write your solution here
}
0/9
Common Bugs to Avoid
Wrong: Board with repeated digits in a row or columnMissing or incorrect checks for row or column constraints before placing a digit.✅ Implement is_valid function to check that digit does not appear in the same row or column before placement.
Wrong: Board with repeated digits in a 3x3 boxBox constraint not checked or off-by-one error in box indexing.✅ Check all cells in the 3x3 box using correct box start indices: rowStart=3*(r//3), colStart=3*(c//3).
Wrong: Incomplete board or no solution foundBacktracking does not revert changes or stops prematurely.✅ Ensure backtracking resets cell to '.' when no digit fits and continues searching other digits.
Wrong: Solver times out on empty or large boardsBrute force backtracking without pruning or heuristics.✅ Implement constraint propagation and choose the most constrained empty cell first to reduce branching.
✓
Test Cases
t1_01basic
Input[[["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"]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

The solver fills each empty cell by trying digits 1-9 and backtracking when constraints are violated, eventually completing the board correctly.

t1_02basic
Input[[["8",".",".",".",".",".",".",".","."],[".",".","3","6",".",".",".",".","."],[".","7",".",".","9",".","2",".","."],[".","5",".",".",".","7",".",".","."],[".",".",".",".","4","5","7",".","."],[".",".",".","1",".",".",".","3","."],[".",".","1",".",".",".",".","6","8"],[".",".","8","5",".",".",".","1","."],[".","9",".",".",".",".","4",".","."]]]
Expected[[["8","1","2","7","5","3","6","4","9"],["9","4","3","6","8","2","1","7","5"],["6","7","5","4","9","1","2","8","3"],["1","5","4","2","3","7","8","9","6"],["3","6","9","8","4","5","7","2","1"],["2","8","7","1","6","9","5","3","4"],["5","2","1","9","7","4","3","6","8"],["4","3","8","5","2","6","9","1","7"],["7","9","6","3","1","8","4","5","2"]]]

Another standard Sudoku puzzle solved by backtracking with constraint checks, filling all empty cells correctly.

t2_01edge
Input[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","."]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

Board with only one empty cell; solver must fill that cell correctly without unnecessary backtracking.

t2_02edge
Input[[["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"]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

Board with multiple empty cells in the same row, column, and box; solver must respect all constraints simultaneously.

t2_03edge
Input[[[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."]]]
Expectednull

Empty board (all cells empty) is a boundary case; solver must handle but will be very slow for brute force.

t3_01corner
Input[[["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"]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

Test to catch greedy approach that fills cells without backtracking, leading to invalid final board.

t3_02corner
Input[[["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"]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

Test to catch confusion between 0/1 constraints and unbounded filling (not applicable here but to ensure no repeated digits).

t3_03corner
Input[[["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"]]]
Expected[[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]]

Test to catch off-by-one errors in indexing 3x3 boxes or rows/columns.

t4_01performance
Input[[[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".",".","."]]]
⏱ Performance - must finish in 2000ms

Empty board with all cells empty (81 empty cells) tests solver performance; brute force backtracking is O(9^81) and will time out.

Practice

(1/5)
1. Given the following code snippet, what is the final output of letterCombinations('23')?
from collections import deque

def letterCombinations(digits):
    if not digits:
        return []
    digit_map = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl',
                 '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
    queue = deque([''])
    for digit in digits:
        letters = digit_map[digit]
        for _ in range(len(queue)):
            prev = queue.popleft()
            for char in letters:
                queue.append(prev + char)
    return list(queue)

print(letterCombinations('23'))
easy
A. ['ad', 'bd', 'cd', 'ae', 'be', 'ce', 'af', 'bf', 'cf']
B. ['abc', 'def']
C. ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']
D. ['a', 'b', 'c', 'd', 'e', 'f']

Solution

  1. Step 1: Trace queue after processing digit '2'

    Initial queue: [''] Letters for '2': 'abc' After processing: ['a', 'b', 'c']
  2. Step 2: Trace queue after processing digit '3'

    Letters for '3': 'def' For each prefix in ['a', 'b', 'c'], append each letter: 'a' + 'd','e','f' -> 'ad','ae','af' 'b' + 'd','e','f' -> 'bd','be','bf' 'c' + 'd','e','f' -> 'cd','ce','cf' Final queue: ['ad','ae','af','bd','be','bf','cd','ce','cf']
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Output matches expected letter combinations for '23' [OK]
Hint: Queue expands combinations breadth-first per digit [OK]
Common Mistakes:
  • Mixing order of combinations
  • Confusing concatenation order
2. You need to generate all possible orderings of a list of unique integers. Which algorithmic approach guarantees that all permutations are generated without duplicates and with optimal time complexity?
easy
A. Backtracking with either a used array or in-place swapping to explore all permutations
B. Sorting the array repeatedly and collecting unique sequences
C. Dynamic programming to build permutations from smaller subproblems
D. Greedy algorithm that picks the next smallest unused element at each step

Solution

  1. Step 1: Understand the problem requires all permutations

    Generating all permutations means enumerating every possible ordering of the input elements without duplicates.
  2. Step 2: Identify the approach that systematically explores all orderings

    Backtracking with a used array or in-place swapping explores all permutations by recursively building sequences or swapping elements, ensuring no duplicates and covering all possibilities.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking is the standard method for generating all permutations [OK]
Hint: Backtracking systematically explores all permutations [OK]
Common Mistakes:
  • Thinking greedy or sorting can generate all permutations without duplicates
3. What is the time complexity of the optimal backtracking solution that generates all valid parentheses sequences for input n?
medium
A. O(2^{2n} * n) because it generates all sequences and checks validity
B. O(n^2) because it builds sequences of length 2n with nested loops
C. O(n!) because it permutes parentheses positions
D. O(\frac{4^n}{n^{3/2}}) because the number of valid sequences is the nth Catalan number

Solution

  1. Step 1: Identify number of valid sequences

    The number of valid parentheses sequences is the nth Catalan number, approximately 4^n / (n^{3/2}).
  2. Step 2: Analyze backtracking time

    Backtracking generates all valid sequences, so time is proportional to number of sequences times sequence length, which is O(4^n / n^{3/2} * n) = O(4^n / n^{1/2}).
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Matches known Catalan number growth for valid parentheses [OK]
Hint: Catalan number growth dominates complexity [OK]
Common Mistakes:
  • Confusing brute force with backtracking complexity
  • Assuming factorial complexity
4. What is the time complexity of the bitmask backtracking solution for counting all N-Queens solutions on an nxn board?
medium
A. O(n^n) because each row tries all columns independently
B. O(2^n) due to bitmask operations over all subsets of columns
C. O(n^3) from checking conflicts and iterating over rows and columns
D. O(n!) because each queen placement reduces available columns by one

Solution

  1. Step 1: Identify branching factor per row

    Each row places one queen in a column not attacked by previous queens, reducing choices roughly by one each time.
  2. Step 2: Calculate total recursive calls

    Thus, total calls approximate n x (n-1) x (n-2) x ... = n! permutations.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Backtracking prunes invalid columns, yielding O(n!) complexity [OK]
Hint: N-Queens backtracking explores permutations -> O(n!) [OK]
Common Mistakes:
  • Confusing bitmask ops with exponential subsets
  • Assuming polynomial due to pruning
5. Suppose you want to modify the palindrome partitioning algorithm to allow reuse of substrings in partitions (i.e., substrings can appear multiple times in different partitions). Which change to the algorithm is necessary to correctly handle this variant without losing valid partitions or causing duplicates?
hard
A. Memoize palindrome checks and reuse results but keep backtracking unchanged
B. Modify backtracking to avoid popping from path to reuse substrings across calls
C. Use a global visited set to skip substrings already used in previous partitions
D. Allow substrings to be reused by resetting path after each complete partition

Solution

  1. Step 1: Understand reuse requirement

    Reusing substrings means substrings can appear multiple times in different partitions, so path management must allow multiple uses.
  2. Step 2: Identify necessary algorithm change

    Memoizing palindrome checks improves efficiency by avoiding repeated palindrome computations, while backtracking logic remains unchanged to generate all valid partitions.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Memoization optimizes palindrome checks without affecting partition generation correctness [OK]
Hint: Memoize palindrome checks to optimize without changing backtracking [OK]
Common Mistakes:
  • Assuming popping affects substring reuse
  • Using visited sets that block valid reuse
  • Resetting path incorrectly losing partitions
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard