42
42
43
43
<!-- 这里可写通用的实现逻辑 -->
44
44
45
+ ** 方法一:枚举**
46
+
47
+ 我们可以枚举字符串数组 ` words ` 中的每个字符串 $w$,判断其是否以 $pref$ 作为前缀,如果是,则答案加一。
48
+
49
+ 时间复杂度 $O(n \times m)$,空间复杂度 $O(1)$。其中 $n$ 和 $m$ 分别是字符串数组 ` words ` 和字符串 $pref$ 的长度。
50
+
51
+ ** 方法二:前缀树**
52
+
53
+ 我们还可以使用前缀树来查询答案。
54
+
55
+ 定义前缀树的每个节点结构如下:
56
+
57
+ - ` children ` :长度为 $26$ 的数组,用于存储当前节点的所有子节点,其中 ` children[i] ` 表示当前节点的子节点;
58
+ - ` cnt ` :所有以当前节点为前缀的字符串的数量。
59
+
60
+ 另外,我们还需要定义两个函数:
61
+
62
+ - 其中一个函数 $insert(w)$ 用于将字符串 $w$ 插入前缀树中;
63
+ - 另一个函数 $search(pref)$ 用于查询以字符串 $pref$ 作为前缀的字符串的数量。查询时,我们从前缀树的根节点开始,遍历字符串 $pref$,如果当前节点的子节点中不存在 $pref[ i] $,则说明 $pref$ 不是任何字符串的前缀,直接返回 $0$。否则,我们继续遍历 $pref$ 的下一个字符,直到遍历完 $pref$,返回当前节点的 ` cnt ` 即可。
64
+
65
+ 有了上述函数,我们就可以查询答案了。
66
+
67
+ 遍历字符串数组 ` words ` ,对于每个字符串 $w$,调用 $insert(w)$ 函数将其插入前缀树中。最后调用 $search(pref)$ 函数作为答案返回即可。
68
+
69
+ 时间复杂度 $O(L)$,空间复杂度 $O(L)$。其中 $L$ 是字符串数组 ` words ` 中所有字符串的长度之和。
70
+
45
71
<!-- tabs:start -->
46
72
47
73
### ** Python3**
@@ -54,6 +80,39 @@ class Solution:
54
80
return sum (w.startswith(pref) for w in words)
55
81
```
56
82
83
+ ``` python
84
+ class Trie :
85
+ def __init__ (self ):
86
+ self .children = [None ] * 26
87
+ self .cnt = 0
88
+
89
+ def insert (self , w ):
90
+ node = self
91
+ for c in w:
92
+ i = ord (c) - ord (' a' )
93
+ if node.children[i] is None :
94
+ node.children[i] = Trie()
95
+ node = node.children[i]
96
+ node.cnt += 1
97
+
98
+ def search (self , pref ):
99
+ node = self
100
+ for c in pref:
101
+ i = ord (c) - ord (' a' )
102
+ if node.children[i] is None :
103
+ return 0
104
+ node = node.children[i]
105
+ return node.cnt
106
+
107
+
108
+ class Solution :
109
+ def prefixCount (self , words : List[str ], pref : str ) -> int :
110
+ tree = Trie()
111
+ for w in words:
112
+ tree.insert(w)
113
+ return tree.search(pref)
114
+ ```
115
+
57
116
### ** Java**
58
117
59
118
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -72,18 +131,44 @@ class Solution {
72
131
}
73
132
```
74
133
75
- ### ** TypeScript**
134
+ ``` java
135
+ class Trie {
136
+ private Trie [] children = new Trie [26 ];
137
+ private int cnt;
138
+
139
+ public void insert (String w ) {
140
+ Trie node = this ;
141
+ for (int i = 0 ; i < w. length(); ++ i) {
142
+ int j = w. charAt(i) - ' a' ;
143
+ if (node. children[j] == null ) {
144
+ node. children[j] = new Trie ();
145
+ }
146
+ node = node. children[j];
147
+ ++ node. cnt;
148
+ }
149
+ }
76
150
77
- ``` ts
78
- function prefixCount(words : string [], pref : string ): number {
79
- const n = pref .length ;
80
- let ans = 0 ;
81
- for (let str of words ) {
82
- if (str .substring (0 , n ) == pref ) {
83
- ans ++ ;
151
+ public int search (String pref ) {
152
+ Trie node = this ;
153
+ for (int i = 0 ; i < pref. length(); ++ i) {
154
+ int j = pref. charAt(i) - ' a' ;
155
+ if (node. children[j] == null ) {
156
+ return 0 ;
157
+ }
158
+ node = node. children[j];
84
159
}
160
+ return node. cnt;
161
+ }
162
+ }
163
+
164
+ class Solution {
165
+ public int prefixCount (String [] words , String pref ) {
166
+ Trie tree = new Trie ();
167
+ for (String w : words) {
168
+ tree. insert(w);
169
+ }
170
+ return tree. search(pref);
85
171
}
86
- return ans ;
87
172
}
88
173
```
89
174
@@ -94,25 +179,126 @@ class Solution {
94
179
public:
95
180
int prefixCount(vector<string >& words, string pref) {
96
181
int ans = 0;
97
- for (auto& w : words)
98
- if (w.find(pref) == 0)
99
- ++ans;
182
+ for (auto& w : words) ans += w.find(pref) == 0;
100
183
return ans;
101
184
}
102
185
};
103
186
```
104
187
188
+ ```cpp
189
+ class Trie {
190
+ public:
191
+ Trie(): children(26), cnt(0) {}
192
+
193
+ void insert(string w) {
194
+ Trie* node = this;
195
+ for (auto& c : w) {
196
+ int i = c - 'a';
197
+ if (!node->children[i]) {
198
+ node->children[i] = new Trie();
199
+ }
200
+ node = node->children[i];
201
+ ++node->cnt;
202
+ }
203
+ }
204
+
205
+ int search(string pref) {
206
+ Trie* node = this;
207
+ for (auto& c : pref) {
208
+ int i = c - 'a';
209
+ if (!node->children[i]) {
210
+ return 0;
211
+ }
212
+ node = node->children[i];
213
+ }
214
+ return node->cnt;
215
+ }
216
+
217
+ private:
218
+ vector<Trie*> children;
219
+ int cnt;
220
+ };
221
+
222
+ class Solution {
223
+ public:
224
+ int prefixCount(vector<string>& words, string pref) {
225
+ Trie* tree = new Trie();
226
+ for (auto& w : words) {
227
+ tree->insert(w);
228
+ }
229
+ return tree->search(pref);
230
+ }
231
+ };
232
+ ```
233
+
105
234
### ** Go**
106
235
107
236
``` go
108
- func prefixCount(words []string, pref string) int {
109
- ans := 0
237
+ func prefixCount (words []string , pref string ) (ans int ) {
110
238
for _ , w := range words {
111
239
if strings.HasPrefix (w, pref) {
112
240
ans++
113
241
}
114
242
}
115
- return ans
243
+ return
244
+ }
245
+ ```
246
+
247
+ ``` go
248
+ type Trie struct {
249
+ children [26 ]*Trie
250
+ cnt int
251
+ }
252
+
253
+ func newTrie () *Trie {
254
+ return &Trie{}
255
+ }
256
+
257
+ func (this *Trie ) insert (w string ) {
258
+ node := this
259
+ for _ , c := range w {
260
+ c -= ' a'
261
+ if node.children [c] == nil {
262
+ node.children [c] = newTrie ()
263
+ }
264
+ node = node.children [c]
265
+ node.cnt ++
266
+ }
267
+ }
268
+
269
+ func (this *Trie ) search (pref string ) int {
270
+ node := this
271
+ for _ , c := range pref {
272
+ c -= ' a'
273
+ if node.children [c] == nil {
274
+ return 0
275
+ }
276
+ node = node.children [c]
277
+ }
278
+ return node.cnt
279
+ }
280
+
281
+ func prefixCount (words []string , pref string ) int {
282
+ tree := newTrie ()
283
+ for _ , w := range words {
284
+ tree.insert (w)
285
+ }
286
+ return tree.search (pref)
287
+ }
288
+ ```
289
+
290
+ ### ** TypeScript**
291
+
292
+ ``` ts
293
+ function prefixCount(words : string [], pref : string ): number {
294
+ const m = pref .length ;
295
+ let ans = 0 ;
296
+ for (const w of words ) {
297
+ if (w .substring (0 , m ) === pref ) {
298
+ ++ ans ;
299
+ }
300
+ }
301
+ return ans ;
116
302
}
117
303
```
118
304
0 commit comments