Each digit maps to a small fixed set of letters, and one letter must be chosen per digit β the output length is fixed at len(digits), only the content varies. That makes this a decision tree with a known depth, branching by 3 or 4 at each level.
Brute Force: Iterative Cartesian Product
Time O(4^n Β· n)Space O(4^n Β· n)Build up the result list by repeatedly taking the Cartesian product with the next digitβs letters: start with [""], and for each digit, form every combination of an existing partial string with every letter of that digit.
class Solution: def letterCombinations(self, digits: str) -> list[str]: if not digits: return [] mapping = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz', } combos = [''] for digit in digits: combos = [prefix + letter for prefix in combos for letter in mapping[digit]] return combosCorrect and reasonably efficient, but it materializes a full intermediate list after every digit rather than exploring the tree depth-first β for problems with pruning opportunities this pattern would waste work, though here (with no invalid combinations to skip) it costs the same asymptotically as backtracking.
Backtracking, One Digit at a Time
OptimalTime O(4^n Β· n)Space O(n)Recurse through digits index by index. At each call, try every letter mapped to the current digit: append it to path, recurse into the next digit, then remove it. A combination is complete once path covers every digit.
class Solution: def letterCombinations(self, digits: str) -> list[str]: if not digits: return [] mapping = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz', } result = [] path = []
def backtrack(index): if index == len(digits): result.append(''.join(path)) return for letter in mapping[digits[index]]: path.append(letter) backtrack(index + 1) path.pop()
backtrack(0) return resultTracing digits = "23" as a decision tree β depth 1 branches over 2βs letters (a,b,c), depth 2 over 3βs letters (d,e,f):
Start with an empty path. Digit 0 is "2" -> try a, b, c.
Complexity: letting n = len(digits), each digit contributes at most 4 choices (digits 7 and 9 have 4 letters), so there are up to 4^n complete combinations, each built in O(n) β O(4^n Β· n) time. Recursion depth and path are bounded by n β O(n) auxiliary space (excluding the output).