Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.

Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
给一串数字,按电话键盘上数字可代表的字母,求出所有可能的组合。
解法1: 递归Recursion,和subset, combination问题类似的DFS+backtracking。先要用HashMap或者数组建立一个从数字到字母的转换表,然后每一层递归遍历当前digits[i]所对应的所有字母,并加入当前combination中传到下一层递归。
解法2: 迭代Iteration。
Java: Recursion, Time: O(3^n), Space: O(n)
public class Solution {
private static final String[] keyboard =
new String[]{ " ", "", "abc", "def", // '0','1','2',...
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
public List<String> letterCombinations(String digits) {
List<String> result = new ArrayList<>();
if (digits.isEmpty()) return result;
dfs(digits, 0, "", result);
return result;
}
private static void dfs(String digits, int cur, String path,
List<String> result) {
if (cur == digits.length()) {
result.add(path);
return;
}
final String str = keyboard[digits.charAt(cur) - '0'];
for (char c : keyboard[digits.charAt(cur) - '0'].toCharArray()) {
dfs(digits, cur + 1, path + c, result);
}
}
}
Java: Iteration, Time: O(3^n), Space: O(1)
public class Solution {
private static final String[] keyboard =
new String[]{ " ", "", "abc", "def", // '0','1','2',...
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
public List<String> letterCombinations(String digits) {
if (digits.isEmpty()) return new ArrayList<>();
List<String> result = new ArrayList<>();
result.add("");
for (char d : digits.toCharArray()) {
final int n = result.size();
final int m = keyboard[d - '0'].length();
// resize to n * m
for (int i = 1; i < m; ++i) {
for (int j = 0; j < n; ++j) {
result.add(result.get(j));
}
}
for (int i = 0; i < result.size(); ++i) {
result.set(i, result.get(i) + keyboard[d - '0'].charAt(i/n));
}
}
return result;
}
}
Java: BFS, LinkedList
public class Solution {
public List<String> letterCombinations(String digits) {
LinkedList<String> res = new LinkedList<>();
if (digits == null || digits.length() == 0) return res;
String[] map = new String[] {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
res.add("");
for (int i = 0; i < digits.length(); i++) {
int index = digits.charAt(i) - '0';
while (res.peek().length() == i) {
String t = res.remove();
for (char c : map[index].toCharArray()) {
res.add(t + c);
}
}
}
return res;
}
}
Java: Recursion, HashMap, Time: O(3^n), Space: O(n)
public class Solution {
public ArrayList<String> letterCombinations(String digits) {
ArrayList<String> result = new ArrayList<String>();
if (digits == null || digits.equals("")) {
return result;
}
Map<Character, char[]> map = new HashMap<Character, char[]>();
map.put('0', new char[] {});
map.put('1', new char[] {});
map.put('2', new char[] { 'a', 'b', 'c' });
map.put('3', new char[] { 'd', 'e', 'f' });
map.put('4', new char[] { 'g', 'h', 'i' });
map.put('5', new char[] { 'j', 'k', 'l' });
map.put('6', new char[] { 'm', 'n', 'o' });
map.put('7', new char[] { 'p', 'q', 'r', 's' });
map.put('8', new char[] { 't', 'u', 'v'});
map.put('9', new char[] { 'w', 'x', 'y', 'z' });
StringBuilder sb = new StringBuilder();
helper(map, digits, sb, result);
return result;
}
private void helper(Map<Character, char[]> map, String digits,
StringBuilder sb, ArrayList<String> result) {
if (sb.length() == digits.length()) {
result.add(sb.toString());
return;
}
for (char c : map.get(digits.charAt(sb.length()))) {
sb.append(c);
helper(map, digits, sb, result);
sb.deleteCharAt(sb.length() - 1);
}
}
}
Java: Iteration, FIFO queue
public class Solution {
private String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
public List<String> letterCombinations(String digits) {
LinkedList<String> ans = new LinkedList<String>();
if(digits.length()<1) return ans;
ans.add("");
for(int i =0; i<digits.length();i++){
int x = digits.charAt(i) - '0';
while(ans.peek().length()==i){
String t = ans.remove();
for(char s : mapping[x].toCharArray())
ans.add(t+s);
}
}
return ans;
}
}
Python: Recursion
class Solution:
def letterCombinations(self, digits):
if not digits:
return []
lookup, result = ["", "", "abc", "def", "ghi", "jkl", "mno",
"pqrs", "tuv", "wxyz"], []
self.letterCombinationsRecu(result, digits, lookup, "", 0)
return result
def letterCombinationsRecu(self, result, digits, lookup, cur, n):
if n == len(digits):
result.append(cur)
else:
for choice in lookup[int(digits[n])]:
self.letterCombinationsRecu(result, digits, lookup, cur + choice, n + 1)
Python: Iteration
class Solution:
def letterCombinations(self, digits):
if not digits:
return []
lookup, result = ["", "", "abc", "def", "ghi", "jkl", "mno",
"pqrs", "tuv", "wxyz"], [""]
for digit in reversed(digits):
choices = lookup[int(digit)]
m, n = len(choices), len(result)
result += [result[i % n] for i in xrange(n, m * n)]
for i in xrange(m * n):
result[i] = choices[i / n] + result[i]
return result
C++: Recursion
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> lettComb;
string dict[] = {" ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
string comb(digits.size(),' ');
findLettComb(digits, 0, dict, comb, lettComb);
return lettComb;
}
void findLettComb(string &digits, int index, string dict[], string &comb, vector<string> &lettComb) {
if(index==digits.size()) {
lettComb.push_back(comb);
return;
}
string lett= dict[digits[index] - '0'];
for(int i=0; i<lett.size(); i++) {
comb[index] = lett[i];
findLettComb(digits, index+1, dict, comb, lettComb);
}
}
};
C++:Iteration
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
if (digits.empty()) return res;
string dict[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
res.push_back("");
for (int i = 0; i < digits.size(); ++i) {
int n = res.size();
string str = dict[digits[i] - '2'];
for (int j = 0; j < n; ++j) {
string tmp = res.front();
res.erase(res.begin());
for (int k = 0; k < str.size(); ++k) {
res.push_back(tmp + str[k]);
}
}
}
return res;
}
};
类似的题目:
[LeetCode] 77. Combinations 全组合
Path Sum II 二叉树路径之和II
Subsets II 子集合II
Permutations 全排列
Permutations II 全排列II
Combination Sum 组合之和
Combination Sum II 组合之和II