forked from soapyigu/LeetCode-Swift
-
Notifications
You must be signed in to change notification settings - Fork 1
/
LetterCombinationsPhoneNumber.swift
52 lines (41 loc) · 1.82 KB
/
LetterCombinationsPhoneNumber.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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
* Question Link: https://leetcode.com/problems/letter-combinations-of-a-phone-number/
* Primary idea: Classic Depth-first Search, create phone board at first
*
* Time Complexity: O(4^n), n stands for length of digits
* Space Complexity: O(n), n stands for length of digits
*
*/
class LetterCombinationsPhoneNumber {
func letterCombinations(_ digits: String) -> [String] {
guard digits.count > 0 else {
return [String]()
}
var combinations = [String](), combination = ""
let numberToStr = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
dfs(&combinations, &combination, numberToStr, digits, 0)
return combinations
}
private func dfs(_ combinations: inout [String], _ combination: inout String, _ numberToStr: [String], _ digits: String, _ index: Int) {
if combination.count == digits.count {
combinations.append(combination)
return
}
let currentStr = fetchCurrentStr(from: digits, at: index, numberToStr)
for char in currentStr {
combination.append(char)
dfs(&combinations, &combination, numberToStr, digits, index + 1)
combination.removeLast()
}
}
private func fetchCurrentStr(from digits: String, at index: Int, _ numberToStr: [String]) -> String {
guard index >= 0 && index < digits.count else {
fatalError("Invalid index")
}
let currentDigitChar = digits[digits.index(digits.startIndex, offsetBy: index)]
guard let currentDigit = Int(String(currentDigitChar)), currentDigit >= 0, currentDigit < numberToStr.count else {
fatalError("Invalid digits")
}
return numberToStr[currentDigit]
}
}