Limited Time Offer:Up to 20% off Hello Interview Premium
Up to 20% off Hello Interview Premium 🎉
Hello Interview
Learn Code
Introduction
Overview
Container With Most Water
Two Sum (Sorted Array)
3-Sum
Triangle Numbers
Move Zeroes
Sort Colors
Trapping Rain Water
Overview
Maximum Sum of Subarrays of Size K
Max Points You Can Obtain From Cards
Max Sum of Distinct Subarrays Length k
Overview
Longest Substring Without Repeating Characters
Longest Repeating Character Replacement
Overview
Can Attend Meetings
Insert Interval
Non-Overlapping Intervals
Merge Intervals
Employee Free Time
Overview
Valid Parentheses
Decode String
Longest Valid Parentheses
Monotonic Stack
Daily Temperatures
Largest Rectangle in Histogram
Overview
Linked List Cycle
Palindrome Linked List
Remove Nth Node From End of List
Reorder List
Swap Nodes in Pairs
Overview
Apple Harvest (Koko Eating Bananas)
Search in Rotated Sorted Array
Split Array Largest Sum
Kth Smallest Element in a Sorted Matrix
Minimum Shipping Capacity
Overview
Kth Largest Element in an Array
K Closest Points to Origin
Find K Closest Elements
Merge K Sorted Lists
Median from Data Stream
Introduction
Fundamentals
Return Values
Maximum Depth of Binary Tree
Path Sum
Passing Values Down and Helper Functions
Validate Binary Search Tree
Calculate Tilt
Diameter of a Binary Tree
Path Sum II
Longest Univalue Path
Graphs Overview
Adjacency List
Copy Graph
Graph Valid Tree
Matrices
Flood Fill
Number of Islands
Surrounded Regions
Pacific Atlantic Water Flow
Introduction
Overview
Level Order Sum
Rightmost Node
Zigzag Level Order
Maximum Width of Binary Tree
Graphs Overview
Minimum Knight Moves
Rotting Oranges
01-Matrix
Bus Routes
Overview
Word Search
Solution Space Trees
Subsets
Generate Parentheses
Combination Sum
Palindrome Partitioning
N-Queens
Overview
Course Schedule
Course Schedule II
Shortest Path Algorithms
Network Delay Time
Cheapest Flights Within K Stops
Path With Minimum Effort
Find City with Fewest Reachable
Fundamentals
Solving a Question with Dynamic Programming
Counting Bits
Decode Ways
Unique Paths
Maximal Square
Longest Increasing Subsequence
Word Break
Maximum Profit in Job Scheduling
Paint House
Paint House II
Minimum Window Subsequence
Overview
Best Time to Buy and Sell Stock
Gas Station
Jump Game
Jump Game II
Partition Labels
Overview
Implement Trie Methods
Prefix Matching
Overview
Count Vowels in Substrings
Subarray Sum Equals K
Spiral Matrix
Rotate Image
Set Matrix Zeroes
Vote For New Content
Pricing
Sign in / Sign up
Search
⌘K
Pricing

Tutor

Backtracking

Solution Space Trees


max (21)341224132;341225102;21365487109
Count: 10
abcValid triangle requires:a + b > c AND a + c > b AND b + c > a(every pair must sum to more than the third side)3511SOURCE23211SOURCE23UNREACHABLE$100$100$100$5000SRC123DST$100$100$1000SRC123DST01233141Threshold: 4Answer: 32 reachable01234231118Threshold: 2Answer: 01 reachable1102233321432263321
In the Overview section, we use Depth-First Search to explore all valid root-to-leaf paths in a binary tree that we are given. In most backtracking problems, we won't be given an explicit tree to traverse. Instead, our algorithm needs to construct the tree based on the problem.

Example: Letter Combinations of a Phone Number

DESCRIPTION
Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.
A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
2: "abc"
3: "def"
4: "ghi"
5: "jkl"
6: "mno"
7: "pqrs"
8: "tuv"
9: "wxyz"
Example:
Input:
"23"
Output:
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
We can think about solving this problem incrementally, using the input "23" as an example.
We start with an empty string, and form all possible combinations that can be made using the first digit.
"2" -> ["a", "b", "c"]
Now we take each of these combinations above and add the letters corresponding to the second digit, "3".
Since "3" maps to "def", we add "d" to "a", "b", and "c", then "e" to "a", "b", and "c", and finally "f" to "a", "b", and "c".
"23" -> ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
If we were to visualize this process a tree, it would look like this, where the leaf nodes represent the final combinations:
abcadaeafbdbebfcdcecf
This tree conceptually represents the "solution space" of all possible letter combinations of the phone number. If we can traverse this tree, we can find all valid combinations.
So how do we do so without an explicit tree to traverse? Let's break it down.

Writing a Backtracking Algorithm

Now that we can visualize the "solution-space" tree, our next step is to write a backtracking solution which uses depth-first search to explore all possible paths in the tree.
Defining the Recursive Function
Conceptually, each node in the tree corresponds to a single recursive call. Each recursive call will make additional recursive calls, which are represented by the edges in the tree.
To define our recursive function, we need to figure out what information we need to pass to each recursive call / node so that it can reach its neighbors, as this determines the parameters of our recursive function.
Let's illustrate with the example of "23":
At the root node, we start with an empty string. The children of the root node are "a", "b", and "c", which correspond to the digit 2. So we can label the root node with 2 parameters, the empty string, and 0, which represents the index of the digit in the input phone number we are currently processing.
"", 0
This suggests that our recursive function should have two arguments: the current combination, and the index of the digit we are currently processing.
Solution
Python
Language
def backtrack(path, idx):
Next, we need to figure out how to explore the neighbors of the root node, which are "a", "b", and "c". We can get "a", "b", "c" by iterating over the letters corresponding to our digit "2", and adding each letter to our current combination (which right now is the empty string). For each of these letters, we make a recursive call with the updated combination and the next digit in the phone number.
"", 0"a", 1"b", 1"c", 1
Since each edge in our tree corresponds to a recursive call, this suggests that the body of our recursive function should iterate over the letters corresponding to the current digit, and make a recursive call for each letter with the updated combination and the next digit in the phone number.
Solution
Python
Language
def backtrack(path, idx):
# base case
...
for letter in phone[digits[idx]]:
backtrack(path + letter, idx + 1)
Those recursive calls lead us to the last level of the tree, which are the leaf nodes. At the leaf nodes, we should add the current combination to our list of valid combinations.
"", 0"a", 1"b", 1"c", 1"ad", 2"ae", 2"af", 2"bd", 2"be", 2"bf", 2"cd", 2"ce", 2"cf", 2
We know we are at a leaf node when the index of the digit we are processing is equal to the length of the phone number. So we can add a base case to our recursive function to check if the index is equal to the length of the phone number. If it is, we add the current combination to our list of valid combinations.
Solution
Python
Language
def backtrack(path, idx):
# base case: we have reached a leaf node
if idx == len(digits):
result.append(path)
return
for letter in phone[digits[idx]]:
backtrack(path + letter, idx + 1)
Finally, in the main function, we kick off the call to our recursive function with the empty string and the index 0 (the root node of our tree).
Solution
Python
Language
def letterCombinations(digits):
phone = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz"
}
def backtrack(path, idx):
if idx == len(digits):
result.append(path)
return
for letter in phone[digits[idx]]:
backtrack(path + letter, idx + 1)
result = []
if digits:
backtrack("", 0)
return result

Summary

The first step in solving a backtracking problem is to visualize the solution-space tree.
  • Each node in the solution-space tree corresponds to a single recursive call.
  • The parameters of the recursive function correspond to the information needed to reach the neighbors of a node.
  • The body of the recursive function should iterate over the neighbors of a node and make recursive calls for each neighbor.
Test Your Knowledge

Login to take the complexity quiz and track your progress

Complexity Analysis
Calculating the time and space complexity of a backtracking algorithm depends on the structure of the solution-space tree. Here are the general guidelines:
  1. Depth of the tree: Often the size of the input (for our phone number problem, this is n)
  2. Branching factor: The number of recursive calls made in the body (for our problem, this is 4)
For our phone number problem:
  • Depth = length of phone number (n)
  • Branching factor = 4 (each digit maps to at most 4 letters)
The tree structure has:
  • 1 node at depth 1
  • 4 nodes at depth 2
  • 4² nodes at depth 3
  • ...
  • 4ⁿ nodes at depth n (leaf nodes)
The total number of nodes is 1 + 4 + 4² + ... + 4ⁿ, which is asymptotically O(4ⁿ).

Solution-Space Tree Examples

The solution-space tree will look different for each backtracking problem, but one common type is a binary tree, where each node in the tree represents a "choose" or "don't choose" decision at that level.
This tree can be used to generate all possible subsets of a list of integers, which we breakdown below:
DESCRIPTION
Given a set of distinct integers, nums, return all possible subsets (the power set), without duplicates.
Example:
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
The solution-space tree for this problem is a binary tree. Each node in the binary tree represents a different subset of the input.
[][1][1,2][1,2,3][1,2][1][1,3][1][][2][2, 3][2][][3][]
So how do we go from one node to its children in this tree? Each level in the tree corresponds to a different element in the input set, and each child node corresponds to either including (left) or excluding (right) the current element in the subset represented by the parent node.
At the root node, where current subset = [], and the current element is 1:
  1. Left Child: We take the current subset and include 1. This gives us the subset [1].
  2. Right Child: We take the current subset and exclude 1. This gives us the subset [].
For the subset [1], we repeat the process, now with current element 2:
  1. Left Child: We take the current subset and include 2. This gives us the subset [1, 2].
  2. Right Child: We take the current subset and exclude 2. This gives us the subset [1].
Given that information, try writing a backtracking solution for this problem on your own!

Mark as read

Next: Subsets

Your account is free and you can post anonymously if you choose.

Unlock Premium Coding Content

Interactive algorithm visualizations
Guided Practice
Recent interview questions
Learn More
Reading Progress

On This Page

Example: Letter Combinations of a Phone Number

Writing a Backtracking Algorithm

Summary

Solution-Space Tree Examples

Questions
Meta SWE Interview QuestionsAmazon SWE Interview QuestionsGoogle SWE Interview QuestionsOpenAI SWE Interview QuestionsEngineering Manager (EM) Interview Questions
Learn
Learn System DesignLearn DSALearn BehavioralLearn ML System DesignLearn Low Level DesignGuided Practice
Links
FAQPricingGift PremiumHello Interview Premium
Legal
Terms and ConditionsPrivacy PolicySecurity
Contact
About UsProduct Support

7511 Greenwood Ave North Unit #4238 Seattle WA 98103


© 2026 Optick Labs Inc. All rights reserved.

Login to track your progress