Sudoku Solver
You can create a recursive function to solve the Sudoku puzzle, filling the empty cells according to the rules. Here’s the code for that:


The function is_valid
checks whether a number can be placed in a specific cell based on the rules of Sudoku. The recursive function solve
attempts to place a number in an empty cell and then recurses to solve the rest of the board. If a solution is found, the board is updated in place. If the current path doesn’t lead to a solution, the function backtracks by setting the cell back to ‘.’ and continues searching.
10 Prerequisite LeetCode Problems
“Sudoku Solver” involves the use of backtracking algorithm to fill a partially filled sudoku. Here are 10 problems for a better understanding:
“Valid Sudoku” (LeetCode Problem #36): This problem requires you to check whether a partially filled Sudoku is valid according to the Sudoku rules or not.
“Subsets” (LeetCode Problem #78): This problem introduces you to the concept of generating all possible subsets of a given set using backtracking.
“Combination Sum” (LeetCode Problem #39): Here, you’ll be using backtracking to find all unique combinations that sum up to a target.
“Permutations” (LeetCode Problem #46): This problem is about finding all possible permutations of a given list of numbers, which requires using a backtracking approach.
“Word Search” (LeetCode Problem #79): This is a good problem to apply backtracking in a 2D grid which is similar to a Sudoku grid.
“Generate Parentheses” (LeetCode Problem #22): This problem uses backtracking to create all possible combinations of wellformed parentheses.
“Palindrome Partitioning” (LeetCode Problem #131): This problem involves backtracking and also introduces the concept of palindromes.
“Restore IP Addresses” (LeetCode Problem #93): This problem requires you to generate all possible valid IP addresses from given string, involving concepts of both string manipulation and backtracking.
“Letter Combinations of a Phone Number” (LeetCode Problem #17): This problem, like many others in this list, requires backtracking to generate all possible letter combinations that the number could represent.
“Binary Watch” (LeetCode Problem #401): This problem helps in understanding combinations and backtracking in a simpler context.


Problem Classification
This problem involves filling up a partially filled grid with numbers such that no number is repeated in any row, column or 3x3 subgrid. It’s a popular puzzle that requires a strategy of backtracking, which involves placing numbers and reverting if it doesn’t lead to a valid solution. Thus, it’s categorized under Number Placement Puzzle.
This problem involves filling up a partially filled grid with numbers ensuring no number repeats in any row, column, or 3x3 subgrid. It’s like solving a popular puzzle where you sometimes need to go back on your steps if they don’t lead to a solution. This is classified as Puzzle Solving / Backtracking.
Category: Puzzle Solving / Backtracking.
Language Agnostic Coding Drills
This code is solving the Sudoku problem using a recursive, backtracking approach.
Understanding Multidimensional Lists: The code uses a 2dimensional list to represent the Sudoku board.
Understanding Conditional Statements: The code uses conditional statements to perform actions based on specific conditions.
Understanding Loop Constructs: The code uses nested loops to iterate over the Sudoku board and check various conditions.
Understanding Functions: The code uses two main functions,
isValid
andsolve
, which are recursively called.Understanding Recursion: The main engine of this code is the recursive function
solve
, which uses backtracking to solve the Sudoku problem.Understanding Backtracking: This is a specific type of recursion where you try out solutions and if they don’t lead to a valid answer, you undo the previous step (or “backtrack”) and try a different path.
Here’s how you can arrange the drills in order of increasing difficulty:
 Manipulating and working with multidimensional lists.
 Understanding and using conditional statements.
 Writing loops and nested loops.
 Writing and using functions.
 Writing recursive functions.
 Implementing backtracking.
The problemsolving approach for this Sudoku solver works like this:
 Start from the top left cell of the Sudoku board.
 If the cell is empty, try to fill it with a number from 1 to 9. But before placing a number, check if it’s valid to place that number in the current cell.
 A number is valid if the same number doesn’t exist in the current row, column, and the 3x3 grid the cell belongs to.
 If placing the number is valid, place it and move to the next cell.
 If placing the number is not valid or if the next cells don’t lead to a solution, remove the number from the current cell and try the next number.
 If none of the numbers can be placed in the current cell, return to the previous cell (backtrack) and try the next number in that cell.
 If all cells are filled and no conflict occurs, it means the Sudoku is solved.
Targeted Drills in Python
Manipulating and working with multidimensional lists:
Drill: Create a 2dimensional list (matrix), then write a function that prints each row on a separate line.
1 2 3 4 5 6
def print_matrix(matrix): for row in matrix: print(row) matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print_matrix(matrix)
Understanding and using conditional statements:
Drill: Write a function that takes an integer as input and prints whether the number is positive, negative or zero.
1 2 3 4 5 6 7 8 9 10 11
def check_number(n): if n > 0: print("Positive") elif n < 0: print("Negative") else: print("Zero") check_number(5) check_number(3) check_number(0)
Writing loops and nested loops:
Drill: Write a function that prints a square pattern with the character ‘*’. The size of the square is determined by the input parameter.
1 2 3 4 5 6 7
def print_square(n): for i in range(n): for j in range(n): print('*', end = '') print() print_square(4)
Writing and using functions:
Drill: Write a function that takes two numbers as parameters and returns their sum.
1 2 3 4
def add(a, b): return a + b print(add(3, 4))
Writing recursive functions:
Drill: Write a recursive function that calculates the factorial of a number.
1 2 3 4 5 6 7
def factorial(n): if n == 0 or n == 1: return 1 else: return n * factorial(n1) print(factorial(5))
Implementing backtracking:
Drill: Write a Python function that solves the Nqueens problem using backtracking. The Nqueens puzzle is the problem of placing N chess queens on an N×N chessboard so that no two queens threaten each other.
This drill is considerably more complex than the previous ones and requires a good understanding of backtracking.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
def solve_n_queens(n): def is_safe(board, row, col): for i in range(col): if board[row][i] == 1: return False for i, j in zip(range(row, 1, 1), range(col, 1, 1)): if board[i][j] == 1: return False for i, j in zip(range(row, n, 1), range(col, 1, 1)): if board[i][j] == 1: return False return True def solve(board, col): if col >= n: return True for i in range(n): if is_safe(board, i, col): board[i][col] = 1 if solve(board, col + 1): return True board[i][col] = 0 return False board = [[0]*n for _ in range(n)] if solve(board, 0): return board else: return None print(solve_n_queens(4))
Remember to always practice with simpler problems and progressively increase the complexity as you get comfortable with the concepts.