Skip to content

Commit 4b9c663

Browse files
committed
17. Letter Combinations of a Phone Number
```Solution.c /** * Note: The returned array must be malloced, assume caller calls free(). */ const char* mapping[] = { "", // 0 "", // 1 "abc", // 2 "def", // 3 "ghi", // 4 "jkl", // 5 "mno", // 6 "pqrs", // 7 "tuv", // 8 "wxyz" // 9 }; void backtrack(char* digits, int index, char* current, char** result, int* count) { if (digits[index] == '\0') { result[*count] = strdup(current); (*count)++; return; } int digit = digits[index] - '0'; if (digit < 2 || digit > 9) { backtrack(digits, index + 1, current, result, count); return; } const char* letters = mapping[digit]; for (int i = 0; letters[i] != '\0'; i++) { current[index] = letters[i]; backtrack(digits, index + 1, current, result, count); } } char** letterCombinations(char* digits, int* returnSize) { if (!digits || digits[0] == '\0') { *returnSize = 0; return NULL; } int len = strlen(digits); int maxSize = 1; for (int i = 0; i < len; i++) { int digit = digits[i] - '0'; if (digit < 2 || digit > 9) { *returnSize = 0; return NULL; } int lettersCount = strlen(mapping[digit]); maxSize *= lettersCount; } char** result = (char**)malloc(maxSize * sizeof(char*)); char* current = (char*)malloc((len + 1) * sizeof(char)); current[len] = '\0'; int count = 0; backtrack(digits, 0, current, result, &count); free(current); *returnSize = count; return result; } ``` ```Solution.cpp class Solution { public: vector<string> letterCombinations(string digits) { if (digits.empty()) return {}; vector<string> mapping = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; vector<string> result; function<void(int, string)> backtrack = [&](int idx, string curr) { if (idx == digits.size()) { result.push_back(curr); return; } for (char c : mapping[digits[idx] - '0']) { backtrack(idx + 1, curr + c); } }; backtrack(0, ""); return result; } }; ``` ```Solution.cs public class Solution { public IList<string> LetterCombinations(string digits) { var result = new List<string>(); if (string.IsNullOrEmpty(digits)) return result; string[] mapping = new string[] { "", // 0 "", // 1 "abc", // 2 "def", // 3 "ghi", // 4 "jkl", // 5 "mno", // 6 "pqrs",// 7 "tuv", // 8 "wxyz" // 9 }; Backtrack(digits, mapping, 0, "", result); return result; } private void Backtrack(string digits, string[] mapping, int index, string current, List<string> result) { if (index == digits.Length) { result.Add(current); return; } string letters = mapping[digits[index] - '0']; foreach (char c in letters) { Backtrack(digits, mapping, index + 1, current + c, result); } } } ``` ```Solution.dart class Solution { List<String> letterCombinations(String digits) { if (digits.isEmpty) return []; Map<String, String> phone = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz', }; List<String> result = []; void backtrack(String combination, int next) { if (next == digits.length) { result.add(combination); return; } String letters = phone[digits[next]] ?? ''; for (int i = 0; i < letters.length; i++) { backtrack(combination + letters[i], next + 1); } } backtrack('', 0); return result; } } ``` ```Solution.erl -spec three_sum_closest(Nums :: [integer()], Target :: integer()) -> integer(). -spec letter_combinations(Digits :: unicode:unicode_binary()) -> [unicode:unicode_binary()]. letter_combinations(Digits) when Digits == <<>> -> []; letter_combinations(Digits) -> Map = #{ <<"2">> => [<<"a">>, <<"b">>, <<"c">>], <<"3">> => [<<"d">>, <<"e">>, <<"f">>], <<"4">> => [<<"g">>, <<"h">>, <<"i">>], <<"5">> => [<<"j">>, <<"k">>, <<"l">>], <<"6">> => [<<"m">>, <<"n">>, <<"o">>], <<"7">> => [<<"p">>, <<"q">>, <<"r">>, <<"s">>], <<"8">> => [<<"t">>, <<"u">>, <<"v">>], <<"9">> => [<<"w">>, <<"x">>, <<"y">>, <<"z">>] }, letter_combinations(Digits, Map). letter_combinations(Digits, Map) -> DigitsList = unicode:characters_to_list(Digits), LettersList = [maps:get(<<D>>, Map, []) || D <- DigitsList], combine(LettersList). combine([]) -> []; combine([H]) -> H; combine([H|T]) -> [<<A/binary, B/binary>> || A <- H, B <- combine(T)]. ``` ```Solution.ex defmodule Solution do @SPEC letter_combinations(digits :: String.t) :: [String.t] def letter_combinations("") do [] end def letter_combinations(digits) do mapping = %{ "2" => ["a", "b", "c"], "3" => ["d", "e", "f"], "4" => ["g", "h", "i"], "5" => ["j", "k", "l"], "6" => ["m", "n", "o"], "7" => ["p", "q", "r", "s"], "8" => ["t", "u", "v"], "9" => ["w", "x", "y", "z"] } digits |> String.graphemes() |> Enum.map(&Map.get(mapping, &1, [])) |> Enum.reduce([""], fn letters, acc -> for prefix <- acc, letter <- letters, do: prefix <> letter end) end end ``` ```Solution.go func letterCombinations(digits string) []string { if len(digits) == 0 { return []string{} } mapping := map[byte]string{ '2': "abc", '3': "def", '4': "ghi", '5': "jkl", '6': "mno", '7': "pqrs", '8': "tuv", '9': "wxyz", } var res []string var backtrack func(index int, path string) backtrack = func(index int, path string) { if index == len(digits) { res = append(res, path) return } letters := mapping[digits[index]] for i := 0; i < len(letters); i++ { backtrack(index+1, path+string(letters[i])) } } backtrack(0, "") return res } ``` ```Solution.java class Solution { public List<String> letterCombinations(String digits) { if (digits == null || digits.length() == 0) return new ArrayList<>(); String[] mapping = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; List<String> result = new ArrayList<>(); backtrack(result, digits, mapping, 0, new StringBuilder()); return result; } private void backtrack(List<String> result, String digits, String[] mapping, int index, StringBuilder current) { if (index == digits.length()) { result.add(current.toString()); return; } String letters = mapping[digits.charAt(index) - '0']; for (char c : letters.toCharArray()) { current.append(c); backtrack(result, digits, mapping, index + 1, current); current.deleteCharAt(current.length() - 1); } } } ``` ```Solution.js /** * @param {string} digits * @return {string[]} */ var letterCombinations = function(digits) { if (!digits || digits.length === 0) return []; const map = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz' }; const result = []; function backtrack(index, path) { if (index === digits.length) { result.push(path); return; } for (const char of map[digits[index]]) { backtrack(index + 1, path + char); } } backtrack(0, ''); return result; }; ``` ```Solution.kt class Solution { fun letterCombinations(digits: String): List<String> { if (digits.isEmpty()) return emptyList() val map = mapOf( '2' to "abc", '3' to "def", '4' to "ghi", '5' to "jkl", '6' to "mno", '7' to "pqrs", '8' to "tuv", '9' to "wxyz" ) val result = mutableListOf<String>() fun backtrack(index: Int, path: String) { if (index == digits.length) { result.add(path) return } for (c in map[digits[index]] ?: "") { backtrack(index + 1, path + c) } } backtrack(0, "") return result } } ``` ```Solution.php class Solution { /** * @param String $digits * @return String[] */ function letterCombinations($digits) { $map = [ '2' => ['a', 'b', 'c'], '3' => ['d', 'e', 'f'], '4' => ['g', 'h', 'i'], '5' => ['j', 'k', 'l'], '6' => ['m', 'n', 'o'], '7' => ['p', 'q', 'r', 's'], '8' => ['t', 'u', 'v'], '9' => ['w', 'x', 'y', 'z'] ]; if ($digits === "") return []; $result = ['']; for ($i = 0; $i < strlen($digits); $i++) { $letters = $map[$digits[$i]] ?? []; $temp = []; foreach ($result as $comb) { foreach ($letters as $letter) { $temp[] = $comb . $letter; } } $result = $temp; } return $result; } } ``` ```Solution.py class Solution: def letterCombinations(self, digits: str) -> List[str]: if not digits: return [] phone = { "2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz" } res = [] def backtrack(index, path): if index == len(digits): res.append(path) return for char in phone[digits[index]]: backtrack(index + 1, path + char) backtrack(0, "") return res ``` ```Solution.rb # @param {String} digits # @return {String[]} def letter_combinations(digits) return [] if digits.empty? phone = { '2' => %w[a b c], '3' => %w[d e f], '4' => %w[g h i], '5' => %w[j k l], '6' => %w[m n o], '7' => %w[p q r s], '8' => %w[t u v], '9' => %w[w x y z] } result = [''] digits.each_char do |digit| result = result.flat_map { |prefix| phone[digit].map { |char| prefix + char } } end result end ``` ```Solution.rkt (define/contract (letter-combinations digits) (-> string? (listof string?)) (define digit-map (hash "2" '("a" "b" "c") "3" '("d" "e" "f") "4" '("g" "h" "i") "5" '("j" "k" "l") "6" '("m" "n" "o") "7" '("p" "q" "r" "s") "8" '("t" "u" "v") "9" '("w" "x" "y" "z"))) (define (combine lst1 lst2) (if (null? lst1) lst2 (apply append (map (λ (x) (map (λ (y) (string-append x y)) lst2)) lst1)))) (if (string=? digits "") '() (let loop ((idx 0) (result '(""))) (if (= idx (string-length digits)) result (let* ((d (substring digits idx (+ idx 1))) (letters (hash-ref digit-map d '()))) (loop (+ idx 1) (combine result letters))))))) ``` ```Solution.rs impl Solution { pub fn letter_combinations(digits: String) -> Vec<String> { if digits.is_empty() { return Vec::new(); } let map = vec![ "", // 0 "", // 1 "abc", // 2 "def", // 3 "ghi", // 4 "jkl", // 5 "mno", // 6 "pqrs",// 7 "tuv", // 8 "wxyz" // 9 ]; let mut res = vec![String::new()]; for d in digits.chars() { let idx = d.to_digit(10).unwrap() as usize; let letters = map[idx]; let mut tmp = Vec::new(); for prefix in &res { for ch in letters.chars() { let mut new_str = prefix.clone(); new_str.push(ch); tmp.push(new_str); } } res = tmp; } res } } ``` ```Solution.scala object Solution { def letterCombinations(digits: String): List[String] = { val digitToLetters = Map( '2' -> "abc", '3' -> "def", '4' -> "ghi", '5' -> "jkl", '6' -> "mno", '7' -> "pqrs", '8' -> "tuv", '9' -> "wxyz" ) if (digits.isEmpty) return List() digits.foldLeft(List("")) { (acc, digit) => for { combination <- acc letter <- digitToLetters.getOrElse(digit, "") } yield combination + letter } } } ``` ```Solution.swift class Solution { func letterCombinations(_ digits: String) -> [String] { if digits.isEmpty { return [] } let mapping: [Character: [String]] = [ "2": ["a", "b", "c"], "3": ["d", "e", "f"], "4": ["g", "h", "i"], "5": ["j", "k", "l"], "6": ["m", "n", "o"], "7": ["p", "q", "r", "s"], "8": ["t", "u", "v"], "9": ["w", "x", "y", "z"] ] var result: [String] = [""] for digit in digits { guard let letters = mapping[digit] else { continue } var temp: [String] = [] for prefix in result { for letter in letters { temp.append(prefix + letter) } } result = temp } return result } } ``` ```Solution.ts function letterCombinations(digits: string): string[] { if (!digits) return []; const map: { [key: string]: string } = { "2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz" }; const result: string[] = []; const backtrack = (comb: string, nextDigits: string) => { if (nextDigits.length === 0) { result.push(comb); return; } for (const letter of map[nextDigits[0]]) { backtrack(comb + letter, nextDigits.slice(1)); } }; backtrack("", digits); return result; } ```
1 parent 8440f60 commit 4b9c663

20 files changed

+514
-0
lines changed

res/ino/477965828.png

304 KB
Loading
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# [**17. Letter Combinations of a Phone Number**](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/)
2+
3+
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**.<br>
4+
A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
5+
6+
<img src="https://raw.githubusercontent.com/leetcoin-releases/leetcode/refs/heads/main/res/ino/477965828.png" style="width: 100%; height: 600;"/>
7+
8+
#### **Example 1:**
9+
```md
10+
Input: digits = "23"
11+
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
12+
```
13+
14+
#### **Example 2:**
15+
```md
16+
Input: digits = ""
17+
Output: []
18+
```
19+
20+
#### **Example 3:**
21+
```md
22+
Input: digits = "2"
23+
Output: ["a","b","c"]
24+
```
25+
26+
#### **Constraints:**
27+
```md
28+
• 0 <= digits.length <= 4
29+
• digits[i] is a digit in the range ['2', '9'].
30+
```
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Note: The returned array must be malloced, assume caller calls free().
3+
*/
4+
const char* mapping[] = {
5+
"", // 0
6+
"", // 1
7+
"abc", // 2
8+
"def", // 3
9+
"ghi", // 4
10+
"jkl", // 5
11+
"mno", // 6
12+
"pqrs", // 7
13+
"tuv", // 8
14+
"wxyz" // 9
15+
};
16+
void backtrack(char* digits, int index, char* current, char** result, int* count) {
17+
if (digits[index] == '\0') {
18+
result[*count] = strdup(current);
19+
(*count)++;
20+
return;
21+
}
22+
int digit = digits[index] - '0';
23+
if (digit < 2 || digit > 9) {
24+
backtrack(digits, index + 1, current, result, count);
25+
return;
26+
}
27+
const char* letters = mapping[digit];
28+
for (int i = 0; letters[i] != '\0'; i++) {
29+
current[index] = letters[i];
30+
backtrack(digits, index + 1, current, result, count);
31+
}
32+
}
33+
char** letterCombinations(char* digits, int* returnSize) {
34+
if (!digits || digits[0] == '\0') {
35+
*returnSize = 0;
36+
return NULL;
37+
}
38+
int len = strlen(digits);
39+
int maxSize = 1;
40+
for (int i = 0; i < len; i++) {
41+
int digit = digits[i] - '0';
42+
if (digit < 2 || digit > 9) {
43+
*returnSize = 0;
44+
return NULL;
45+
}
46+
int lettersCount = strlen(mapping[digit]);
47+
maxSize *= lettersCount;
48+
}
49+
char** result = (char**)malloc(maxSize * sizeof(char*));
50+
char* current = (char*)malloc((len + 1) * sizeof(char));
51+
current[len] = '\0';
52+
int count = 0;
53+
backtrack(digits, 0, current, result, &count);
54+
free(current);
55+
*returnSize = count;
56+
return result;
57+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public:
3+
vector<string> letterCombinations(string digits) {
4+
if (digits.empty()) return {};
5+
vector<string> mapping = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
6+
vector<string> result;
7+
function<void(int, string)> backtrack = [&](int idx, string curr) {
8+
if (idx == digits.size()) {
9+
result.push_back(curr);
10+
return;
11+
}
12+
for (char c : mapping[digits[idx] - '0']) {
13+
backtrack(idx + 1, curr + c);
14+
}
15+
};
16+
backtrack(0, "");
17+
return result;
18+
}
19+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
public class Solution {
2+
public IList<string> LetterCombinations(string digits) {
3+
var result = new List<string>();
4+
if (string.IsNullOrEmpty(digits)) return result;
5+
string[] mapping = new string[] {
6+
"", // 0
7+
"", // 1
8+
"abc", // 2
9+
"def", // 3
10+
"ghi", // 4
11+
"jkl", // 5
12+
"mno", // 6
13+
"pqrs",// 7
14+
"tuv", // 8
15+
"wxyz" // 9
16+
};
17+
Backtrack(digits, mapping, 0, "", result);
18+
return result;
19+
}
20+
private void Backtrack(string digits, string[] mapping, int index, string current, List<string> result) {
21+
if (index == digits.Length) {
22+
result.Add(current);
23+
return;
24+
}
25+
string letters = mapping[digits[index] - '0'];
26+
foreach (char c in letters) {
27+
Backtrack(digits, mapping, index + 1, current + c, result);
28+
}
29+
}
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
List<String> letterCombinations(String digits) {
3+
if (digits.isEmpty) return [];
4+
Map<String, String> phone = {
5+
'2': 'abc',
6+
'3': 'def',
7+
'4': 'ghi',
8+
'5': 'jkl',
9+
'6': 'mno',
10+
'7': 'pqrs',
11+
'8': 'tuv',
12+
'9': 'wxyz',
13+
};
14+
List<String> result = [];
15+
void backtrack(String combination, int next) {
16+
if (next == digits.length) {
17+
result.add(combination);
18+
return;
19+
}
20+
String letters = phone[digits[next]] ?? '';
21+
for (int i = 0; i < letters.length; i++) {
22+
backtrack(combination + letters[i], next + 1);
23+
}
24+
}
25+
backtrack('', 0);
26+
return result;
27+
}
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
-spec letter_combinations(Digits :: unicode:unicode_binary()) -> [unicode:unicode_binary()].
2+
letter_combinations(Digits) when Digits == <<>> ->
3+
[];
4+
letter_combinations(Digits) ->
5+
Map = #{
6+
<<"2">> => [<<"a">>, <<"b">>, <<"c">>],
7+
<<"3">> => [<<"d">>, <<"e">>, <<"f">>],
8+
<<"4">> => [<<"g">>, <<"h">>, <<"i">>],
9+
<<"5">> => [<<"j">>, <<"k">>, <<"l">>],
10+
<<"6">> => [<<"m">>, <<"n">>, <<"o">>],
11+
<<"7">> => [<<"p">>, <<"q">>, <<"r">>, <<"s">>],
12+
<<"8">> => [<<"t">>, <<"u">>, <<"v">>],
13+
<<"9">> => [<<"w">>, <<"x">>, <<"y">>, <<"z">>]
14+
},
15+
letter_combinations(Digits, Map).
16+
letter_combinations(Digits, Map) ->
17+
DigitsList = unicode:characters_to_list(Digits),
18+
LettersList = [maps:get(<<D>>, Map, []) || D <- DigitsList],
19+
combine(LettersList).
20+
combine([]) -> [];
21+
combine([H]) -> H;
22+
combine([H|T]) ->
23+
[<<A/binary, B/binary>> || A <- H, B <- combine(T)].
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule Solution do
2+
@spec letter_combinations(digits :: String.t) :: [String.t]
3+
def letter_combinations("") do
4+
[]
5+
end
6+
def letter_combinations(digits) do
7+
mapping = %{
8+
"2" => ["a", "b", "c"],
9+
"3" => ["d", "e", "f"],
10+
"4" => ["g", "h", "i"],
11+
"5" => ["j", "k", "l"],
12+
"6" => ["m", "n", "o"],
13+
"7" => ["p", "q", "r", "s"],
14+
"8" => ["t", "u", "v"],
15+
"9" => ["w", "x", "y", "z"]
16+
}
17+
digits
18+
|> String.graphemes()
19+
|> Enum.map(&Map.get(mapping, &1, []))
20+
|> Enum.reduce([""], fn letters, acc ->
21+
for prefix <- acc, letter <- letters, do: prefix <> letter
22+
end)
23+
end
24+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
func letterCombinations(digits string) []string {
2+
if len(digits) == 0 {
3+
return []string{}
4+
}
5+
mapping := map[byte]string{
6+
'2': "abc",
7+
'3': "def",
8+
'4': "ghi",
9+
'5': "jkl",
10+
'6': "mno",
11+
'7': "pqrs",
12+
'8': "tuv",
13+
'9': "wxyz",
14+
}
15+
var res []string
16+
var backtrack func(index int, path string)
17+
backtrack = func(index int, path string) {
18+
if index == len(digits) {
19+
res = append(res, path)
20+
return
21+
}
22+
letters := mapping[digits[index]]
23+
for i := 0; i < len(letters); i++ {
24+
backtrack(index+1, path+string(letters[i]))
25+
}
26+
}
27+
backtrack(0, "")
28+
return res
29+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public List<String> letterCombinations(String digits) {
3+
if (digits == null || digits.length() == 0) return new ArrayList<>();
4+
String[] mapping = {
5+
"", "", "abc", "def", "ghi", "jkl",
6+
"mno", "pqrs", "tuv", "wxyz"
7+
};
8+
List<String> result = new ArrayList<>();
9+
backtrack(result, digits, mapping, 0, new StringBuilder());
10+
return result;
11+
}
12+
private void backtrack(List<String> result, String digits, String[] mapping, int index, StringBuilder current) {
13+
if (index == digits.length()) {
14+
result.add(current.toString());
15+
return;
16+
}
17+
String letters = mapping[digits.charAt(index) - '0'];
18+
for (char c : letters.toCharArray()) {
19+
current.append(c);
20+
backtrack(result, digits, mapping, index + 1, current);
21+
current.deleteCharAt(current.length() - 1);
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)