Phone Number Mnemonics
Phone Number Mnemonics
Category
Recursion
Difficulty
Medium
Problem Statement
Given a string of digits (0-9) representing a phone number, return all possible letter combinations that the number could represent based on the traditional phone keypad mapping (e.g., 2 -> "abc", 3 -> "def", ..., 9 -> "wxyz"). Digits 0 and 1 map to themselves only.
Intuition
Each digit maps to a set of possible characters. To generate all combinations, we make a choice for the first digit, then recursively generate all combinations for the remaining digits. This is a classic backtracking problem where the branching factor at each level depends on how many letters the current digit maps to (3 or 4 typically).
Approach
- Define the phone keypad mapping: a dictionary from each digit to its corresponding letters.
- Use a recursive function that takes the current digit index and a current combination being built.
- Base case: when the index equals the length of the phone number, add the current combination to the result.
- Recursive step: for each letter mapped to the current digit, append it to the combination and recurse on the next digit.
- Return all collected combinations.
Pseudocode
KEYPAD = {
"0": ["0"], "1": ["1"],
"2": ["a","b","c"], "3": ["d","e","f"],
"4": ["g","h","i"], "5": ["j","k","l"],
"6": ["m","n","o"], "7": ["p","q","r","s"],
"8": ["t","u","v"], "9": ["w","x","y","z"]
}
function phoneNumberMnemonics(phoneNumber):
result = []
current = array of size len(phoneNumber)
generateCombinations(0, phoneNumber, current, result)
return result
function generateCombinations(idx, phoneNumber, current, result):
if idx == len(phoneNumber):
result.append(join(current))
return
digit = phoneNumber[idx]
for letter in KEYPAD[digit]:
current[idx] = letter
generateCombinations(idx + 1, phoneNumber, current, result)
Time & Space Complexity
- Time: O(4^n * n) where n is the length of the phone number. In the worst case, every digit maps to 4 letters, giving 4^n combinations, and each combination takes O(n) to construct.
- Space: O(4^n * n) for storing all combinations. The recursion stack uses O(n) space.
Key Insights
- Using a mutable array for the current combination and only joining at the base case is more efficient than string concatenation at each level.
- Digits 0 and 1 map to themselves, so they contribute a branching factor of 1 (no increase in combinations).
- Digits 7 and 9 have 4 letters while others have 3, making the worst case 4^n rather than 3^n.
- This is a Cartesian product problem: we compute the product of the letter sets for each digit.
Edge Cases
- Empty phone number: return an empty list (or a list containing an empty string, depending on spec).
- Phone number with only 0s and 1s: only one combination (the digits themselves).
- Single digit: return the list of letters for that digit.
- Very long phone numbers: output size grows exponentially, so practical limits apply.