Phone Keypad Letter Combinations
Problem
On a phone keypad, 2 = abc, 3 = def, 4 = ghi, 5 = jkl, 6 = mno, 7 = pqrs, 8 = tuv and 9 = wxyz. Read a string of digits from 2 to 9. Print all letter combinations the digits can stand for, one per line, in dictionary order.
Constraints
- 1 <= length <= 6
Examples
Input
23
Output
ad ae af bd be bf cd ce cf
Solutions
Every digit adds a level to the recursion tree, and every letter of the digit is a branch. With a mutable StringBuilder you must remove the last letter after the call (backtracking); with immutable strings a new string is made at each step.
/*
* Problem : Keypad words.
* Input : A string of digits.
* Output : All words.
* Approach: Backtracking.
* Time : O(4^n * n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: pick a letter for the digit at position index, then move to the next digit.
static void combine(String digits, int index, StringBuilder current, String[] letters, java.util.List<String> result) {
// Step 2: Base case. We chose a letter for every digit: save the word.
if (index == digits.length()) {
result.add(current.toString());
return;
}
// Step 3: Try each letter of this digit in order. After the recursive call, remove the letter (backtrack).
String options = letters[digits.charAt(index) - '0'];
for (int i = 0; i < options.length(); i++) {
current.append(options.charAt(i));
combine(digits, index + 1, current, letters, result);
current.deleteCharAt(current.length() - 1);
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String s) {
String[] letters = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
java.util.List<String> result = new java.util.ArrayList<>();
combine(s.trim(), 0, new StringBuilder(), letters, result);
return result.toArray(new String[0]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.hasNextLine() ? scanner.nextLine() : "";
System.out.println(String.join("\n", solve(s)));
}
}
Hints (1)
- What must you undo after the recursive call when you use a StringBuilder?