Skip to content

Commit 94e1a74

Browse files
committed
feat: add solutions to lc problem: No.2185
No.2185.Counting Words With a Given Prefix
1 parent c4f665b commit 94e1a74

File tree

5 files changed

+383
-40
lines changed

5 files changed

+383
-40
lines changed

solution/2100-2199/2185.Counting Words With a Given Prefix/README.md

Lines changed: 201 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@
4242

4343
<!-- 这里可写通用的实现逻辑 -->
4444

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+
4571
<!-- tabs:start -->
4672

4773
### **Python3**
@@ -54,6 +80,39 @@ class Solution:
5480
return sum(w.startswith(pref) for w in words)
5581
```
5682

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+
57116
### **Java**
58117

59118
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -72,18 +131,44 @@ class Solution {
72131
}
73132
```
74133

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+
}
76150

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];
84159
}
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);
85171
}
86-
return ans;
87172
}
88173
```
89174

@@ -94,25 +179,126 @@ class Solution {
94179
public:
95180
int prefixCount(vector<string>& words, string pref) {
96181
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;
100183
return ans;
101184
}
102185
};
103186
```
104187
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+
105234
### **Go**
106235

107236
```go
108-
func prefixCount(words []string, pref string) int {
109-
ans := 0
237+
func prefixCount(words []string, pref string) (ans int) {
110238
for _, w := range words {
111239
if strings.HasPrefix(w, pref) {
112240
ans++
113241
}
114242
}
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;
116302
}
117303
```
118304

0 commit comments

Comments
 (0)