题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = “23”
输出:[“ad”,”ae”,”af”,”bd”,”be”,”bf”,”cd”,”ce”,”cf”]
示例 2:
输入:digits = “”
输出:[]
示例 3:
输入:digits = “2”
输出:[“a”,”b”,”c”]
提示:
- 0 <= digits.length <= 4
- digits[i] 是范围 [‘2’, ‘9’] 的一个数字。
解决方法
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public: vector<string> letterCombinations(string digits) { if (digits.empty()) { return {}; } vector<string> phone = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; vector<string> combinations; backtrack(digits, 0, "", combinations, phone); return combinations; } private: void backtrack(const string& digits, int index, string current, vector<string>& combinations, const vector<string>& phone) { if (index == digits.length()) { combinations.push_back(current); return; } string letters = phone[digits[index] - '0']; for (char letter : letters) { current.push_back(letter); backtrack(digits, index + 1, current, combinations, phone); current.pop_back(); } } };
|
结果
执行用时 : 4 ms, 击败 31.65% 使用 C++ 的用户
内存消耗 : 6.75 MB, 击败 75.08% 使用 C++ 的用户
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public List<String> letterCombinations(String digits) { List<String> combinations = new ArrayList<>(); if (digits == null || digits.length() == 0) { return combinations; } String[] phone = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; backtrack(digits, 0, new StringBuilder(), combinations, phone); return combinations; } private void backtrack(String digits, int index, StringBuilder current, List<String> combinations, String[] phone) { if (index == digits.length()) { combinations.add(current.toString()); return; } String letters = phone[digits.charAt(index) - '0']; for (char letter : letters.toCharArray()) { current.append(letter); backtrack(digits, index + 1, current, combinations, phone); current.deleteCharAt(current.length() - 1); } } }
|
结果
执行用时 : 0 ms, 击败 100.00% 使用 Java 的用户
内存消耗 : 40.78 MB, 击败 15.89% 使用 Java 的用户
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution(object): def letterCombinations(self, digits): if not digits: return [] phone = { '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'] } def backtrack(index, path): if index == len(digits): combinations.append(''.join(path)) return for letter in phone[digits[index]]: path.append(letter) backtrack(index + 1, path) path.pop() combinations = [] backtrack(0, []) return combinations
|
结果
执行用时 : 20 ms, 击败 40.96% 使用 Python 的用户
内存消耗 : 13.01 MB, 击败 69.30% 使用 Python 的用户
Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution: def letterCombinations(self, digits: str) -> List[str]: if not digits: return [] phone = { '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'] } def backtrack(index, path): if index == len(digits): combinations.append(''.join(path)) return for letter in phone[digits[index]]: path.append(letter) backtrack(index + 1, path) path.pop() combinations = [] backtrack(0, []) return combinations
|
结果
执行用时 : 36 ms, 击败 89.86% 使用 Python3 的用户
内存消耗 : 16.86 MB, 击败 16.18% 使用 Python3 的用户
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
char* phone[] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; void backtrack(char* digits, int index, char* path, char** combinations, int* count) { if (digits[index] == '\0') { combinations[*count] = strdup(path); (*count)++; return; } int digit = digits[index] - '0'; char* letters = phone[digit]; for (int i = 0; i < strlen(letters); i++) { path[index] = letters[i]; backtrack(digits, index + 1, path, combinations, count); } } char** letterCombinations(char* digits, int* returnSize) { if (digits == NULL || *digits == '\0') { *returnSize = 0; return NULL; } int len = strlen(digits); int total_combinations = 1; for (int i = 0; i < len; i++) { int digit = digits[i] - '0'; total_combinations *= strlen(phone[digit]); } char** combinations = (char**)malloc(total_combinations * sizeof(char*)); char* path = (char*)malloc((len + 1) * sizeof(char)); path[len] = '\0'; int count = 0; backtrack(digits, 0, path, combinations, &count); free(path); *returnSize = count; return combinations; }
|
结果
执行用时 : 0 ms, 击败 100.00% 使用 C 的用户
内存消耗 : 6.61 MB, 击败 31.77% 使用 C 的用户
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Solution { private readonly string[] phone = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; public IList<string> LetterCombinations(string digits) { IList<string> combinations = new List<string>(); if (string.IsNullOrEmpty(digits)) { return combinations; } Backtrack(digits, 0, new List<char>(), combinations); return combinations; } private void Backtrack(string digits, int index, List<char> path, IList<string> combinations) { if (index == digits.Length) { combinations.Add(new string(path.ToArray())); return; } int digit = digits[index] - '0'; string letters = phone[digit]; foreach (char letter in letters) { path.Add(letter); Backtrack(digits, index + 1, path, combinations); path.RemoveAt(path.Count - 1); } } }
|
结果
执行用时 : 108 ms, 击败 87.74% 使用 C# 的用户
内存消耗 : 46.07 MB, 击败 5.37% 使用 C# 的用户
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
var letterCombinations = function(digits) { if (digits === null || digits.length === 0) { return []; } const phone = { '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'] }; const combinations = []; const backtrack = (index, path) => { if (index === digits.length) { combinations.push(path.join('')); return; } const letters = phone[digits[index]]; for (let letter of letters) { path.push(letter); backtrack(index + 1, path); path.pop(); } }; backtrack(0, []); return combinations; };
|
结果
执行用时 : 56 ms, 击败 84.24% 使用 JavaScript 的用户
内存消耗 : 47.66 MB, 击败 8.30% 使用 JavaScript 的用户
TypeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| function letterCombinations(digits: string): string[] { if (!digits || digits.length === 0) { return []; } const phone: { [key: string]: 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'] }; const combinations: string[] = []; const backtrack = (index: number, path: string[]) => { if (index === digits.length) { combinations.push(path.join('')); return; } const letters = phone[digits.charAt(index)]; for (let letter of letters) { path.push(letter); backtrack(index + 1, path); path.pop(); } }; backtrack(0, []); return combinations; }
|
结果
执行用时 : 76 ms, 击败 7.96% 使用 TypeScript 的用户
内存消耗 : 50.34 MB, 击败 5.09% 使用 TypeScript 的用户
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Solution {
function letterCombinations($digits) { if ($digits === "") { return []; } $phone = [ '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'] ]; $combinations = []; $this->backtrack($digits, 0, '', $combinations, $phone); return $combinations; } function backtrack($digits, $index, $path, &$combinations, $phone) { if ($index === strlen($digits)) { $combinations[] = $path; return; } $letters = $phone[$digits[$index]]; foreach ($letters as $letter) { $this->backtrack($digits, $index + 1, $path . $letter, $combinations, $phone); } } }
|
结果
执行用时 : 12 ms, 击败 18.52% 使用 PHP 的用户
内存消耗 : 19.43 MB, 击败 11.11% 使用 PHP 的用户
Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { let phone: [Character: [Character]] = [ "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"] ] func letterCombinations(_ digits: String) -> [String] { guard !digits.isEmpty else { return [] } var combinations = [String]() backtrack(Array(digits), 0, "", &combinations) return combinations } func backtrack(_ digits: [Character], _ index: Int, _ path: String, _ combinations: inout [String]) { if index == digits.count { combinations.append(path) return } let currentDigit = digits[index] guard let letters = phone[currentDigit] else { return } for letter in letters { backtrack(digits, index + 1, path + String(letter), &combinations) } } }
|
结果
执行用时 : 0 ms, 击败 100.00% 使用 Swift 的用户
内存消耗 : 15.64 MB, 击败 15.04% 使用 Swift 的用户
Kotlin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { val phone = mapOf( '2' to listOf('a', 'b', 'c'), '3' to listOf('d', 'e', 'f'), '4' to listOf('g', 'h', 'i'), '5' to listOf('j', 'k', 'l'), '6' to listOf('m', 'n', 'o'), '7' to listOf('p', 'q', 'r', 's'), '8' to listOf('t', 'u', 'v'), '9' to listOf('w', 'x', 'y', 'z') ) fun letterCombinations(digits: String): List<String> { if (digits.isEmpty()) { return emptyList() } val combinations = mutableListOf<String>() backtrack(digits.toCharArray(), 0, StringBuilder(), combinations) return combinations } private fun backtrack(digits: CharArray, index: Int, path: StringBuilder, combinations: MutableList<String>) { if (index == digits.size) { combinations.add(path.toString()) return } val letters = phone[digits[index]] ?: return for (letter in letters) { path.append(letter) backtrack(digits, index + 1, path, combinations) path.deleteCharAt(path.length - 1) } } }
|
结果
执行用时 : 216 ms, 击败 5.45% 使用 Kotlin 的用户
内存消耗 : 37.51 MB, 击败 10.91% 使用 Kotlin 的用户
Dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { Map<String, List<String>> phone = { '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'] }; List<String> letterCombinations(String digits) { List<String> combinations = []; if (digits.isEmpty) { return combinations; } _backtrack(digits, 0, '', combinations); return combinations; } void _backtrack(String digits, int index, String current, List<String> combinations) { if (index == digits.length) { combinations.add(current); return; } List<String> letters = phone[digits[index]]!; for (var letter in letters) { _backtrack(digits, index + 1, current + letter, combinations); } } }
|
结果
执行用时 : 296 ms, 击败 -% 使用 Dart 的用户
内存消耗 : 147.34 MB, 击败 100.00% 使用 Dart 的用户
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var phone = map[string][]string{ "2": []string{"a", "b", "c"}, "3": []string{"d", "e", "f"}, "4": []string{"g", "h", "i"}, "5": []string{"j", "k", "l"}, "6": []string{"m", "n", "o"}, "7": []string{"p", "q", "r", "s"}, "8": []string{"t", "u", "v"}, "9": []string{"w", "x", "y", "z"}, } func letterCombinations(digits string) []string { var combinations []string if digits == "" { return combinations } var backtrack func(index int, path string) backtrack = func(index int, path string) { if index == len(digits) { combinations = append(combinations, path) return } letters := phone[string(digits[index])] for _, letter := range letters { backtrack(index+1, path+letter) } } backtrack(0, "") return combinations }
|
结果
执行用时 : 4 ms, 击败 9.81% 使用 Go 的用户
内存消耗 : 1.94 MB, 击败 39.95% 使用 Go 的用户
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
PHONE = { '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'] } def letter_combinations(digits) return [] if digits.empty? combinations = [] backtrack(digits, 0, '', combinations) combinations end def backtrack(digits, index, path, combinations) if index == digits.length combinations << path return end letters = PHONE[digits[index]] letters.each do |letter| backtrack(digits, index + 1, path + letter, combinations) end end
|
结果
执行用时 : 76 ms, 击败 25.00% 使用 Ruby 的用户
内存消耗 : 206.65 MB, 击败 25.00% 使用 Ruby 的用户
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| object Solution { val phone = Map( '2' -> List("a", "b", "c"), '3' -> List("d", "e", "f"), '4' -> List("g", "h", "i"), '5' -> List("j", "k", "l"), '6' -> List("m", "n", "o"), '7' -> List("p", "q", "r", "s"), '8' -> List("t", "u", "v"), '9' -> List("w", "x", "y", "z") ) def letterCombinations(digits: String): List[String] = { if (digits.isEmpty) { return List() } var combinations = List[String]() def backtrack(index: Int, path: String): Unit = { if (index == digits.length) { combinations = path :: combinations return } val letters = phone(digits(index)) letters.foreach(letter => backtrack(index + 1, path + letter)) } backtrack(0, "") combinations.reverse } }
|
结果
执行用时 : 452 ms, 击败 100.00% 使用 Scala 的用户
内存消耗 : 53.96 MB, 击败 100.00% 使用 Scala 的用户
Rust
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| impl Solution { pub fn letter_combinations(digits: String) -> Vec<String> { let phone = [ ('2', "abc"), ('3', "def"), ('4', "ghi"), ('5', "jkl"), ('6', "mno"), ('7', "pqrs"), ('8', "tuv"), ('9', "wxyz"), ] .iter() .cloned() .collect::<std::collections::HashMap<_, _>>(); if digits.is_empty() { return vec![]; } let mut result = vec!["".to_string()]; for digit in digits.chars() { if let Some(letters) = phone.get(&digit) { let mut temp = Vec::new(); for letter in letters.chars() { for item in &result { temp.push(item.clone() + &letter.to_string()); } } result = temp; } } result } }
|
结果
执行用时 : 0 ms, 击败 100.00% 使用 Rust 的用户
内存消耗 : 2.14 MB, 击败 26.85% 使用 Rust 的用户
Racket
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| (define letter-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 (get-letters n) (hash-ref letter-map n)) (define/contract (letter-combinations digits) (-> string? (listof string?)) (if (= 0 (string-length digits)) '() (map list->string (char-combinations (string->list digits))))) (define/contract (char-combinations ns) (-> (listof char?) (listof (listof char?))) (if (null? ns) '(()) (for*/list ([rest-combinations (char-combinations (cdr ns))] [current-letter (get-letters (car ns))]) (cons current-letter rest-combinations))))
|
结果
执行用时 : 184 ms, 击败 100.00% 使用 Racket 的用户
内存消耗 : 98.10 MB, 击败 -% 使用 Racket 的用户
Erlang
暂时未解决
结果
执行用时 : ms, 击败 % 使用 Erlang 的用户
内存消耗 : MB, 击败 % 使用 Erlang 的用户
Elixir
暂时未解决
结果
执行用时 : ms, 击败 % 使用 Elixir 的用户
内存消耗 : MB, 击败 % 使用 Elixir 的用户