Skip to content

Commit 7823f60

Browse files
authored
feat: add solutions to lcci problem: No.16.20 (doocs#1048)
16.20.T9
1 parent 1ac0eec commit 7823f60

12 files changed

+353
-3
lines changed

lcci/16.20.T9/README.md

+126
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>在老式手机上,用户通过数字键盘输入,手机将提供与这些数字相匹配的单词列表。每个数字映射到0至4个字母。给定一个数字序列,实现一个算法来返回匹配单词的列表。你会得到一张含有有效单词的列表。映射如下图所示:</p>
910
![](./images/17_telephone_keypad.png)
1011
<p><strong>示例 1:</strong></p>
@@ -26,22 +27,147 @@
2627

2728
<!-- 这里可写通用的实现逻辑 -->
2829

30+
**方法一:逆向思维**
31+
32+
我们考虑一种正向的解法,遍历字符串 $num$ 中的每个数字,将其映射到对应的字母,然后将所有的字母组合起来,得到所有可能的单词,再与给定的单词列表进行比较,若单词在列表中,则将其加入答案。这种解法的时间复杂度为 $O(4^n)$,其中 $n$ 为字符串 $num$ 的长度,显然会超时。
33+
34+
我们不妨考虑逆向的解法,遍历给定的单词列表,对于每个单词 $w$,判断其是否能够由字符串 $num$ 中的数字组成。若能够组成,则将其加入答案。那么问题的关键在于如何判断一个单词是否能够由字符串 $num$ 中的数字组成。我们只需要遍历单词 $w$ 的每个字母,将其还原为对应的数字,逐个与字符串 $num$ 中的数字进行比较,若相同,则说明单词 $w$ 可以由字符串 $num$ 中的数字组成。
35+
36+
时间复杂度 $O(m \times n)$,空间复杂度 $O(C)$。其中 $m$ 和 $n$ 分别是单词列表的长度和字符串 $num$ 的长度;而 $C$ 为字符集大小,本题中字符集大小为 $26$。
37+
2938
<!-- tabs:start -->
3039

3140
### **Python3**
3241

3342
<!-- 这里可写当前语言的特殊实现逻辑 -->
3443

3544
```python
45+
class Solution:
46+
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
47+
def check(w: str) -> bool:
48+
return all(d[c] == num[i] for i, c in enumerate(w))
3649

50+
d = {c: d for c, d in zip(ascii_lowercase, "22233344455566677778889999")}
51+
return [w for w in words if check(w)]
52+
```
53+
54+
```python
55+
class Solution:
56+
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
57+
trans = str.maketrans(ascii_lowercase, "22233344455566677778889999")
58+
return [w for w in words if w.translate(trans) == num]
3759
```
3860

3961
### **Java**
4062

4163
<!-- 这里可写当前语言的特殊实现逻辑 -->
4264

4365
```java
66+
class Solution {
67+
public List<String> getValidT9Words(String num, String[] words) {
68+
String s = "22233344455566677778889999";
69+
int[] d = new int[26];
70+
for (int i = 0; i < 26; ++i) {
71+
d[i] = s.charAt(i);
72+
}
73+
List<String> ans = new ArrayList<>();
74+
int n = num.length();
75+
for (String w : words) {
76+
boolean ok = true;
77+
for (int i = 0; i < n; ++i) {
78+
if (d[w.charAt(i) - 'a'] != num.charAt(i)) {
79+
ok = false;
80+
break;
81+
}
82+
}
83+
if (ok) {
84+
ans.add(w);
85+
}
86+
}
87+
return ans;
88+
}
89+
}
90+
```
91+
92+
### **C++**
93+
94+
```cpp
95+
class Solution {
96+
public:
97+
vector<string> getValidT9Words(string num, vector<string>& words) {
98+
string s = "22233344455566677778889999";
99+
int d[26];
100+
for (int i = 0; i < 26; ++i) {
101+
d[i] = s[i];
102+
}
103+
vector<string> ans;
104+
int n = num.size();
105+
for (auto& w : words) {
106+
bool ok = true;
107+
for (int i = 0; i < n; ++i) {
108+
if (d[w[i] - 'a'] != num[i]) {
109+
ok = false;
110+
}
111+
}
112+
if (ok) {
113+
ans.emplace_back(w);
114+
}
115+
}
116+
return ans;
117+
}
118+
};
119+
```
120+
121+
### **Go**
122+
123+
```go
124+
func getValidT9Words(num string, words []string) (ans []string) {
125+
s := "22233344455566677778889999"
126+
d := [26]rune{}
127+
for i, c := range s {
128+
d[i] = c
129+
}
130+
for _, w := range words {
131+
ok := true
132+
for i, c := range w {
133+
if d[c-'a'] != rune(num[i]) {
134+
ok = false
135+
break
136+
}
137+
}
138+
if ok {
139+
ans = append(ans, w)
140+
}
141+
}
142+
return
143+
}
144+
```
44145

146+
### **TypeScript**
147+
148+
```ts
149+
function getValidT9Words(num: string, words: string[]): string[] {
150+
const s = '22233344455566677778889999';
151+
const d: string[] = Array(26);
152+
for (let i = 0; i < 26; ++i) {
153+
d[i] = s[i];
154+
}
155+
const ans: string[] = [];
156+
const n = num.length;
157+
for (const w of words) {
158+
let ok = true;
159+
for (let i = 0; i < n; ++i) {
160+
if (d[w[i].charCodeAt(0) - 97] !== num[i]) {
161+
ok = false;
162+
break;
163+
}
164+
}
165+
if (ok) {
166+
ans.push(w);
167+
}
168+
}
169+
return ans;
170+
}
45171
```
46172

47173
### **...**

lcci/16.20.T9/README_EN.md

+125-2
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,139 @@
2828
<li><code>words[i].length == num.length</code></li>
2929
<li><code>There are no number 0 and 1 in num</code>.</li>
3030
</ul>
31+
3132
## Solutions
33+
3234
<!-- tabs:start -->
35+
3336
### **Python3**
37+
38+
```python
39+
class Solution:
40+
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
41+
def check(w: str) -> bool:
42+
return all(d[c] == num[i] for i, c in enumerate(w))
43+
44+
d = {c: d for c, d in zip(ascii_lowercase, "22233344455566677778889999")}
45+
return [w for w in words if check(w)]
46+
```
47+
3448
```python
49+
class Solution:
50+
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
51+
trans = str.maketrans(ascii_lowercase, "22233344455566677778889999")
52+
return [w for w in words if w.translate(trans) == num]
53+
```
3554

36-
````
3755
### **Java**
56+
3857
```java
58+
class Solution {
59+
public List<String> getValidT9Words(String num, String[] words) {
60+
String s = "22233344455566677778889999";
61+
int[] d = new int[26];
62+
for (int i = 0; i < 26; ++i) {
63+
d[i] = s.charAt(i);
64+
}
65+
List<String> ans = new ArrayList<>();
66+
int n = num.length();
67+
for (String w : words) {
68+
boolean ok = true;
69+
for (int i = 0; i < n; ++i) {
70+
if (d[w.charAt(i) - 'a'] != num.charAt(i)) {
71+
ok = false;
72+
break;
73+
}
74+
}
75+
if (ok) {
76+
ans.add(w);
77+
}
78+
}
79+
return ans;
80+
}
81+
}
82+
```
83+
84+
### **C++**
85+
86+
```cpp
87+
class Solution {
88+
public:
89+
vector<string> getValidT9Words(string num, vector<string>& words) {
90+
string s = "22233344455566677778889999";
91+
int d[26];
92+
for (int i = 0; i < 26; ++i) {
93+
d[i] = s[i];
94+
}
95+
vector<string> ans;
96+
int n = num.size();
97+
for (auto& w : words) {
98+
bool ok = true;
99+
for (int i = 0; i < n; ++i) {
100+
if (d[w[i] - 'a'] != num[i]) {
101+
ok = false;
102+
}
103+
}
104+
if (ok) {
105+
ans.emplace_back(w);
106+
}
107+
}
108+
return ans;
109+
}
110+
};
111+
```
112+
113+
### **Go**
39114
40-
````
115+
```go
116+
func getValidT9Words(num string, words []string) (ans []string) {
117+
s := "22233344455566677778889999"
118+
d := [26]rune{}
119+
for i, c := range s {
120+
d[i] = c
121+
}
122+
for _, w := range words {
123+
ok := true
124+
for i, c := range w {
125+
if d[c-'a'] != rune(num[i]) {
126+
ok = false
127+
break
128+
}
129+
}
130+
if ok {
131+
ans = append(ans, w)
132+
}
133+
}
134+
return
135+
}
136+
```
137+
138+
### **TypeScript**
139+
140+
```ts
141+
function getValidT9Words(num: string, words: string[]): string[] {
142+
const s = '22233344455566677778889999';
143+
const d: string[] = Array(26);
144+
for (let i = 0; i < 26; ++i) {
145+
d[i] = s[i];
146+
}
147+
const ans: string[] = [];
148+
const n = num.length;
149+
for (const w of words) {
150+
let ok = true;
151+
for (let i = 0; i < n; ++i) {
152+
if (d[w[i].charCodeAt(0) - 97] !== num[i]) {
153+
ok = false;
154+
break;
155+
}
156+
}
157+
if (ok) {
158+
ans.push(w);
159+
}
160+
}
161+
return ans;
162+
}
163+
```
41164

42165
### **...**
43166

lcci/16.20.T9/Solution.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
vector<string> getValidT9Words(string num, vector<string>& words) {
4+
string s = "22233344455566677778889999";
5+
int d[26];
6+
for (int i = 0; i < 26; ++i) {
7+
d[i] = s[i];
8+
}
9+
vector<string> ans;
10+
int n = num.size();
11+
for (auto& w : words) {
12+
bool ok = true;
13+
for (int i = 0; i < n; ++i) {
14+
if (d[w[i] - 'a'] != num[i]) {
15+
ok = false;
16+
}
17+
}
18+
if (ok) {
19+
ans.emplace_back(w);
20+
}
21+
}
22+
return ans;
23+
}
24+
};

lcci/16.20.T9/Solution.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
func getValidT9Words(num string, words []string) (ans []string) {
2+
s := "22233344455566677778889999"
3+
d := [26]rune{}
4+
for i, c := range s {
5+
d[i] = c
6+
}
7+
for _, w := range words {
8+
ok := true
9+
for i, c := range w {
10+
if d[c-'a'] != rune(num[i]) {
11+
ok = false
12+
break
13+
}
14+
}
15+
if ok {
16+
ans = append(ans, w)
17+
}
18+
}
19+
return
20+
}

lcci/16.20.T9/Solution.java

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public List<String> getValidT9Words(String num, String[] words) {
3+
String s = "22233344455566677778889999";
4+
int[] d = new int[26];
5+
for (int i = 0; i < 26; ++i) {
6+
d[i] = s.charAt(i);
7+
}
8+
List<String> ans = new ArrayList<>();
9+
int n = num.length();
10+
for (String w : words) {
11+
boolean ok = true;
12+
for (int i = 0; i < n; ++i) {
13+
if (d[w.charAt(i) - 'a'] != num.charAt(i)) {
14+
ok = false;
15+
break;
16+
}
17+
}
18+
if (ok) {
19+
ans.add(w);
20+
}
21+
}
22+
return ans;
23+
}
24+
}

lcci/16.20.T9/Solution.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Solution:
2+
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
3+
trans = str.maketrans(ascii_lowercase, "22233344455566677778889999")
4+
return [w for w in words if w.translate(trans) == num]

lcci/16.20.T9/Solution.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function getValidT9Words(num: string, words: string[]): string[] {
2+
const s = '22233344455566677778889999';
3+
const d: string[] = Array(26);
4+
for (let i = 0; i < 26; ++i) {
5+
d[i] = s[i];
6+
}
7+
const ans: string[] = [];
8+
const n = num.length;
9+
for (const w of words) {
10+
let ok = true;
11+
for (let i = 0; i < n; ++i) {
12+
if (d[w[i].charCodeAt(0) - 97] !== num[i]) {
13+
ok = false;
14+
break;
15+
}
16+
}
17+
if (ok) {
18+
ans.push(w);
19+
}
20+
}
21+
return ans;
22+
}

0 commit comments

Comments
 (0)