Sudoku Solver Using Backtracking in DSA C - Time & Space Complexity
We want to understand how the time needed to solve a Sudoku puzzle changes as the puzzle size or difficulty changes.
Specifically, how the backtracking method's steps grow with the puzzle's empty cells.
Analyze the time complexity of the following Sudoku solver code using backtracking.
bool solveSudoku(int board[9][9]) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (board[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isSafe(board, row, col, num)) {
board[row][col] = num;
if (solveSudoku(board))
return true;
board[row][col] = 0;
}
}
return false;
}
}
}
return true;
}
This code tries numbers 1 to 9 in empty cells, checks if safe, and uses recursion to fill the board.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Trying numbers 1 to 9 in each empty cell and recursively solving the rest.
- How many times: For each empty cell, up to 9 attempts; recursion explores many combinations until solution or failure.
As the number of empty cells increases, the number of possible number placements grows very fast.
| Input Size (empty cells) | Approx. Operations |
|---|---|
| 10 | Up to 9^10 = 3,486,784,401 tries |
| 20 | Up to 9^20 = 1.21e+19 tries |
| 30 | Up to 9^30 = 2.06e+28 tries |
Pattern observation: The operations grow exponentially with the number of empty cells, making the problem very costly for many blanks.
Time Complexity: O(9^m) where m is the number of empty cells
This means the time needed grows exponentially as more cells need filling, because each cell can try up to 9 numbers.
[X] Wrong: "The solver always tries 81 cells with 9 numbers each, so it's just 81*9 = 729 steps."
[OK] Correct: The solver tries many combinations recursively, not just one pass. The number of tries multiplies for each empty cell, causing exponential growth.
Understanding this exponential growth helps you explain why backtracking can be slow and when it's suitable. It shows your grasp of recursive problem solving and complexity.
"What if we limit the numbers tried in each cell to only valid candidates instead of all 9? How would the time complexity change?"
Practice
Solution
Step 1: Understand backtracking role
Backtracking tries numbers in empty cells and removes them if they cause conflicts.Step 2: Compare other options
Sorting or random assignment does not solve Sudoku logically; filling zeros is incorrect.Final Answer:
To try possible numbers and undo choices if they lead to conflicts -> Option BQuick Check:
Backtracking = Try and undo choices [OK]
- Thinking backtracking sorts the grid
- Assuming backtracking fills zeros
- Believing numbers are assigned randomly
Solution
Step 1: Understand C syntax for if condition
In C, conditions must be inside parentheses and followed by braces for blocks.Step 2: Analyze options
if (isSafe(row, col, num)) { place num; } uses correct syntax: if(condition) { ... }. Others miss parentheses or use wrong brackets.Final Answer:
if (isSafe(row, col, num)) { place num; } -> Option AQuick Check:
C if syntax = if(condition) { } [OK]
- Omitting parentheses in if condition
- Using square brackets instead of parentheses
- Adding semicolon after if condition
int board[9][9] = {
{5,3,0,0,7,0,0,0,0},
{6,0,0,1,9,5,0,0,0},
{0,9,8,0,0,0,0,6,0},
{8,0,0,0,6,0,0,0,3},
{4,0,0,8,0,3,0,0,1},
{7,0,0,0,2,0,0,0,6},
{0,6,0,0,0,0,2,8,0},
{0,0,0,4,1,9,0,0,5},
{0,0,0,0,8,0,0,7,9}
};
if (solveSudoku(board)) {
printBoard(board);
} else {
printf("No solution exists\n");
}Solution
Step 1: Understand the given board and solveSudoku function
The board is a valid Sudoku puzzle with empty cells as 0. solveSudoku uses backtracking to fill it.Step 2: Predict output of solveSudoku
Since the puzzle is solvable, solveSudoku returns true and printBoard prints the completed board.Final Answer:
The completed Sudoku board printed correctly -> Option DQuick Check:
Solvable board = completed print [OK]
- Assuming no solution exists for valid puzzles
- Expecting compilation error without full code
- Thinking infinite loop happens without base case
bool solveSudoku(int board[9][9]) {
int row, col;
if (!findEmptyCell(board, &row, &col))
return true;
for (int num = 1; num <= 9; num++) {
if (isSafe(board, row, col, num)) {
board[row][col] = num;
if (solveSudoku(board))
return true;
board[row][col] = 0;
}
}
return false;
}Solution
Step 1: Check base case and recursion
Base case returns true if no empty cell found, stopping recursion correctly.Step 2: Verify backtracking steps
After trying a number, if it fails, cell resets to 0, allowing other tries.Step 3: Confirm loop range
Loop runs from 1 to 9, which is correct for Sudoku numbers.Final Answer:
No bug; code works correctly -> Option CQuick Check:
Backtracking code correct = no bug [OK]
- Forgetting to reset cell after failed attempt
- Wrong loop range including 0
- Missing base case causing infinite recursion
Solution
Step 1: Understand backtracking efficiency
Trying all numbers blindly is slow; skipping checks causes wrong solutions.Step 2: Analyze constraint propagation
Constraint propagation narrows choices before backtracking, reducing search space and speeding solving.Step 3: Evaluate other options
Random filling is inefficient; skipping constraints breaks Sudoku rules.Final Answer:
Use constraint propagation to reduce possible numbers before backtracking -> Option AQuick Check:
Constraint propagation = faster solving [OK]
- Trying numbers in fixed order without pruning
- Random filling wastes time
- Ignoring constraints breaks puzzle rules
Ready to prove it?
Pass the test and this pattern moves unknown
