150NeetCode 150

78.Letter Combinations of a Phone Number

MediumBacktracking · 8/9

Problem

Given a string digits containing digits 2–9, return all letter combinations the number could represent on a classic phone keypad. The answer may be in any order.

The mapping is: 2 → abc, 3 → def, 4 → ghi, 5 → jkl, 6 → mno, 7 → pqrs, 8 → tuv, 9 → wxyz. If digits is empty, return an empty list.

Examples

Input:  digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
Explanation: 3 letters for '2' times 3 letters for '3' = 9 strings.
Input:  digits = ""
Output: []
Input:  digits = "2"
Output: ["a","b","c"]

Constraints

  • 0 <= digits.length <= 4
  • digits[i] is a digit in the range ['2', '9'].

💡 Key Insight

This is a Cartesian product: position i of the answer is any letter of digits[i]'s group. Build strings one digit at a time — either breadth-first (extend every partial string with every letter of the next digit) or depth-first with a single StringBuilder that you append to and then trim back. There are up to 4^n results of length n, so O(n · 4^n) is unavoidable.

Iterative Queue (BFS)

TimeO(n · 4^n)SpaceO(n · 4^n)

Intuition

Start with one empty prefix. For each digit, replace every prefix with all of its one-letter extensions. After processing all digits, the prefixes are exactly the answers.

Algorithm

  1. If digits is empty, return [].
  2. result = [""].
  3. For each digit d:
    • next = []; for each prefix in result and each letter of map[d], add prefix + letter to next.
    • result = next.
  4. Return result.

Visualization

digits = "23"

start        : [""]
digit '2'    : ["a", "b", "c"]
digit '3'    : ["ad","ae","af","bd","be","bf","cd","ce","cf"]

Code

java
import java.util.*;

class Solution {
    private static final String[] KEYS = {
        "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
    };

    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<>();
        if (digits.isEmpty()) return result;
        result.add("");
        for (char d : digits.toCharArray()) {
            List<String> next = new ArrayList<>();
            for (String prefix : result) {
                for (char letter : KEYS[d - '0'].toCharArray()) {
                    next.add(prefix + letter); // extend each prefix by one letter
                }
            }
            result = next;
        }
        return result;
    }
}

Complexity

  • Time: O(n · 4^n) — up to 4^n strings, each built by copying a prefix of length up to n.
  • Space: O(n · 4^n) — the previous round's list is held while the next is built.

Complexity Comparison

Approach Time Space (extra)
Iterative Queue O(n · 4^n) O(n · 4^n)
Backtracking O(n · 4^n) O(n)

Common Pitfalls

  • Returning [""] for empty input — the expected answer is [].
  • Forgetting that 7 and 9 have four letters, so the bound is 4^n, not 3^n.
  • Indexing the key array with digits.charAt(i) instead of digits.charAt(i) - '0'.
  • Not deleting the last character after recursion, so letters accumulate across branches.