Letter Combinations of a Phone Number medium
Problem Statement
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 1
Input: digits = "23" Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
Example 2
Input: digits = "" Output: []
Steps
-
Base Case: If the input string
digits
is empty, return an empty list. This handles the case where there are no digits to process. -
Mapping: Create a dictionary or array to map digits to their corresponding letters. This will make it easy to look up letters for each digit.
-
Recursive Approach (Backtracking): We'll use a recursive function to generate combinations.
- The function will take the current combination being built (
combination
), the index of the digit being processed (digitIndex
), and the list of digits (digits
). - Base Case: If
digitIndex
reaches the end of thedigits
string, add the currentcombination
to the result list and return. - Recursive Step: For the digit at
digits[digitIndex]
, get its corresponding letters from the mapping. Iterate through these letters. For each letter:- Append the letter to the
combination
. - Recursively call the function with the updated
combination
and the nextdigitIndex
. - Remove the letter from the
combination
(backtracking) to explore other possibilities.
- Append the letter to the
- The function will take the current combination being built (
-
Result: The recursive function will explore all possible combinations, and the result list will contain all the valid letter combinations.
Explanation
The solution uses backtracking, a powerful technique for exploring all possible solutions to a problem. Imagine a tree where each level represents a digit. Each branch at a level represents a letter corresponding to that digit. Backtracking systematically explores each branch, adding a letter to the current combination, and then removing it to explore other branches. This ensures we don't miss any possible combination.
Code
using System;
using System.Collections.Generic;
public class Solution {
public IList<string> LetterCombinations(string digits) {
IList<string> result = new List<string>();
if (string.IsNullOrEmpty(digits)) return result;
Dictionary<char, string> mapping = new Dictionary<char, string>() {
{'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"},
{'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"}
};
Backtrack(result, mapping, digits, 0, "");
return result;
}
private void Backtrack(IList<string> result, Dictionary<char, string> mapping, string digits, int digitIndex, string combination) {
if (digitIndex == digits.Length) {
result.Add(combination);
return;
}
char digit = digits[digitIndex];
string letters = mapping[digit];
foreach (char letter in letters) {
Backtrack(result, mapping, digits, digitIndex + 1, combination + letter);
}
}
}
Complexity
-
Time Complexity: O(4^N * N), where N is the length of the input digits string. In the worst case, each digit can map to 4 letters, and we need to construct combinations of length N. The N factor comes from string concatenation in each recursive call.
-
Space Complexity: O(N) due to the recursive call stack. The space used by the
result
list is also proportional to the number of combinations, which is bounded by O(4^N).