Bird
Raised Fist0
Interview PrepbacktrackingmediumAmazonFacebookGoogleBloomberg

Letter Combinations of Phone Number

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
</>
IDE
def letterCombinations(digits: str) -> list:public List<String> letterCombinations(String digits)vector<string> letterCombinations(string digits)function letterCombinations(digits)
def letterCombinations(digits):
    # Write your solution here
    pass
class Solution {
    public List<String> letterCombinations(String digits) {
        // Write your solution here
        return new ArrayList<>();
    }
}
#include <vector>
#include <string>
using namespace std;

vector<string> letterCombinations(string digits) {
    // Write your solution here
    return {};
}
function letterCombinations(digits) {
    // Write your solution here
}
0/10
Common Bugs to Avoid
Wrong: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce"]Missing last combination 'cf' due to off-by-one error in loop over letters.Change loop condition to include all letters: for char in digit_map[digits[index]]:
Wrong: ["a", "b", "c"]Returns only letters for first digit ignoring subsequent digits (greedy approach).Implement full backtracking recursion that processes all digits, not just the first.
Wrong: ["pw", "px", "py", "qw", "qx", "qy", "rw", "rx", "ry", "sw", "sx", "sy"]Digits with 4 letters ('7' and '9') handled as if they have 3 letters, missing last letters 'pz' and 'qz' etc.Iterate over full letter string length for digits '7' and '9'.
Wrong: []No base case for empty input, causing function to return empty list or error.Add early return: if not digits: return []
Wrong: ["a", "b", "c", "a", "b", "c"]Duplicates due to incorrect handling of repeated digits or global state not reset.Ensure recursion path is local and no global state causes duplicates.
Test Cases
t1_01basic
Input"23"
Expected["ad","ae","af","bd","be","bf","cd","ce","cf"]

Digit '2' maps to 'abc', digit '3' maps to 'def'. All combinations of letters from these two sets are returned.

t1_02basic
Input"79"
Expected["pw","px","py","pz","qw","qx","qy","qz","rw","rx","ry","rz","sw","sx","sy","sz"]

Digit '7' maps to 'pqrs', digit '9' maps to 'wxyz'. All combinations of letters from these two sets are returned.

t2_01edge
Input""
Expected[]

Empty input string returns empty list as no digits to map.

t2_02edge
Input"2"
Expected["a","b","c"]

Single digit '2' maps to letters 'abc', so output is those letters individually.

t2_03edge
Input"22"
Expected["aa","ab","ac","ba","bb","bc","ca","cb","cc"]

Repeated digit '2' twice means combinations of letters from 'abc' twice, including repeated letters.

t2_04edge
Input"2345"
Expected["adgj","adgk","adgl","adhj","adhk","adhl","adij","adik","adil","aegj","aegk","aegl","aehj","aehk","aehl","aeij","aeik","aeil","afgj","afgk","afgl","afhj","afhk","afhl","afij","afik","afil","bdgj","bdgk","bdgl","bdhj","bdhk","bdhl","bdij","bdik","bdil","begj","begk","begl","behj","behk","behl","beij","beik","beil","bfgj","bfgk","bfgl","bfhj","bfhk","bfhl","bfij","bfik","bfil","cdgj","cdgk","cdgl","cdhj","cdhk","cdhl","cdij","cdik","cdil","cegj","cegk","cegl","cehj","cehk","cehl","ceij","ceik","ceil","cfgj","cfgk","cfgl","cfhj","cfhk","cfhl","cfij","cfik","cfil"]

Maximum length input with digits '2','3','4','5' mapping to 'abc','def','ghi','jkl'. All combinations must be generated.

t3_01corner
Input"234"
Expected["adg","adh","adi","aeg","aeh","aei","afg","afh","afi","bdg","bdh","bdi","beg","beh","bei","bfg","bfh","bfi","cdg","cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"]

Digits '2', '3', '4' map to 'abc', 'def', 'ghi' respectively. All combinations must be generated.

t3_02corner
Input"79"
Expected["pw","px","py","pz","qw","qx","qy","qz","rw","rx","ry","rz","sw","sx","sy","sz"]

Digits '7' and '9' map to letters with 4 letters each. Tests handling of digits with 4 letters.

t3_03corner
Input"2345"
Expected["adgj","adgk","adgl","adhj","adhk","adhl","adij","adik","adil","aegj","aegk","aegl","aehj","aehk","aehl","aeij","aeik","aeil","afgj","afgk","afgl","afhj","afhk","afhl","afij","afik","afil","bdgj","bdgk","bdgl","bdhj","bdhk","bdhl","bdij","bdik","bdil","begj","begk","begl","behj","behk","behl","beij","beik","beil","bfgj","bfgk","bfgl","bfhj","bfhk","bfhl","bfij","bfik","bfil","cdgj","cdgk","cdgl","cdhj","cdhk","cdhl","cdij","cdik","cdil","cegj","cegk","cegl","cehj","cehk","cehl","ceij","ceik","ceil","cfgj","cfgk","cfgl","cfhj","cfhk","cfhl","cfij","cfik","cfil"]

Maximum length input with digits '2','3','4','5' mapping to 'abc','def','ghi','jkl'. All combinations must be generated.

t4_01performance
Input{"_description":"n=4 at constraint boundary - executor generates this input"}
⏱ Performance - must finish in 2000ms

Input length n=4, maximum allowed. Algorithm must run in O(4^n * n) time within 2 seconds.

Practice

(1/5)
1. You are given a numeric string and a target integer. You need to insert binary operators (+, -, *) between digits to form expressions that evaluate to the target. Which algorithmic approach guarantees finding all valid expressions efficiently while handling operator precedence and avoiding invalid operands like those with leading zeros?
easy
A. Backtracking with pruning and careful operand parsing to explore all operator insertions
B. Breadth-first search enumerating all possible expressions without pruning
C. Dynamic programming that stores sub-expression results without operator precedence handling
D. Greedy approach that inserts operators at fixed intervals without backtracking

Solution

  1. Step 1: Understand problem requirements

    The problem requires exploring all ways to insert operators to reach a target, respecting operator precedence and avoiding invalid operands like those with leading zeros.
  2. Step 2: Identify suitable algorithm

    Backtracking with pruning and operand parsing systematically explores all valid expressions, correctly handles precedence (especially multiplication), and prunes invalid paths early.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking explores all valid expressions with pruning [OK]
Hint: Backtracking explores all operator insertions with pruning [OK]
Common Mistakes:
  • Assuming greedy or DP can handle operator precedence and invalid operands
2. Consider the following BFS-based code snippet for removing invalid parentheses:
from collections import deque

def is_valid(s: str) -> bool:
    count = 0
    for c in s:
        if c == '(': count += 1
        elif c == ')':
            count -= 1
            if count < 0:
                return False
    return count == 0

def remove_invalid_parentheses_bfs(s: str):
    res = []
    visited = set([s])
    queue = deque([s])
    found = False

    while queue:
        size = len(queue)
        for _ in range(size):
            curr = queue.popleft()
            if is_valid(curr):
                res.append(curr)
                found = True
            if found:
                continue
            for i in range(len(curr)):
                if curr[i] not in ('(', ')'):
                    continue
                next_str = curr[:i] + curr[i+1:]
                if next_str not in visited:
                    visited.add(next_str)
                    queue.append(next_str)
    return res

print(remove_invalid_parentheses_bfs("()())()"))
What is the output of this code?
easy
A. ["()()()"]
B. ["()()()", "(())()"]
C. ["(())()"]
D. ["()())()"]

Solution

  1. Step 1: Trace BFS levels for input "()())()"

    Initial string is invalid. BFS removes one parenthesis at each position generating candidates. The first valid strings found are "()()()" and "(())()".
  2. Step 2: Confirm both valid strings are collected

    Since BFS stops adding new states after finding valid strings at current level, both minimal removal results are returned.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Both minimal valid strings are returned [OK]
Hint: BFS returns all minimal valid strings at first valid level [OK]
Common Mistakes:
  • Returning only one valid string
  • Returning original invalid string
  • Missing one minimal valid string
3. Consider the following snippet from an optimized Sudoku solver using backtracking with heuristics. Given the board below, what is the length of candidates for the first empty cell chosen after sorting empties by candidate count? Board: [['5', '3', '.', '.', '7', '.', '.', '.', '.'], ['6', '.', '.', '1', '9', '5', '.', '.', '.'], ['.', '9', '8', '.', '.', '.', '.', '6', '.'], ['8', '.', '.', '.', '6', '.', '.', '.', '3'], ['4', '.', '.', '8', '.', '3', '.', '.', '1'], ['7', '.', '.', '.', '2', '.', '.', '.', '6'], ['.', '6', '.', '.', '.', '.', '2', '8', '.'], ['.', '.', '.', '4', '1', '9', '.', '.', '5'], ['.', '.', '.', '.', '8', '.', '.', '7', '9']] Code snippet:
def get_candidates(r, c):
    b = (r//3)*3 + c//3
    return [ch for ch in '123456789' if ch not in rows[r] and ch not in cols[c] and ch not in boxes[b]]

empties.sort(key=lambda x: len(get_candidates(x[0], x[1])))
first_empty = empties[0]
candidates_len = len(get_candidates(first_empty[0], first_empty[1]))
What is the value of candidates_len?
easy
A. 2
B. 3
C. 4
D. 5

Solution

  1. Step 1: Identify first empty cell after sorting

    Check empties and compute candidates for each; the cell with fewest candidates is chosen first.
  2. Step 2: Calculate candidates for first empty cell (0,2)

    Row 0 has {'5','3','7'}, column 2 has {'8'}, box 0 has {'5','3','6','9','8'}. Candidates are digits not in any of these sets: '1','2','4'. So length is 3.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Counting candidates for (0,2) yields 3 [OK]
Hint: Count candidates by excluding row, column, box digits [OK]
Common Mistakes:
  • Forgetting box constraints
  • Miscounting candidates for first empty cell
4. You are given a 2D grid of characters and a target string. You need to determine if the string can be formed by sequentially adjacent cells (horizontally or vertically) without revisiting any cell. Which algorithmic approach best guarantees an optimal solution for this problem?
easy
A. Backtracking with in-place marking and exploring all four directions
B. Dynamic Programming with memoization to store partial matches
C. Greedy search by always choosing the next matching character closest to the start
D. Breadth-first search (BFS) to explore all possible paths simultaneously

Solution

  1. Step 1: Understand problem constraints

    The problem requires checking if a word can be formed by adjacent cells without reuse, which is a classic backtracking scenario.
  2. Step 2: Identify suitable algorithm

    Backtracking with in-place marking efficiently explores all paths while preventing revisiting cells, guaranteeing correctness and optimal pruning.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking explores all valid paths with pruning [OK]
Hint: Backtracking fits adjacency and no-reuse constraints [OK]
Common Mistakes:
  • Assuming greedy or DP can solve adjacency constraints optimally
5. If the problem changes so that numbers can be reused multiple times in the permutation (i.e., repetition allowed), which modification to the algorithm is correct?
hard
A. Use a greedy approach to pick the smallest available number at each step until length n is reached.
B. Use the same factorial-based approach but do not remove numbers from the list after selection.
C. Modify factorial computations to account for repeated elements and use a multiset permutation formula.
D. Generate all permutations with backtracking and stop when the k-th is found, since factorial indexing no longer applies.

Solution

  1. Step 1: Understand repetition impact

    Allowing reuse breaks the factorial number system assumption because permutations count changes drastically.
  2. Step 2: Identify correct approach

    Backtracking with early stop can generate permutations with repetition and find the k-th one, as direct factorial indexing is invalid.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Factorial indexing fails with repetition; backtracking is correct fallback [OK]
Hint: Factorial indexing requires unique elements; repetition breaks it [OK]
Common Mistakes:
  • Trying to reuse factorial indexing without adjustment
  • Ignoring repetition changes permutation count
  • Assuming greedy works for k-th permutation with repetition