Skip to content

Commit d582d74

Browse files
authored
feat: add solutions to lc problem: No.1858 (#2043)
No.1858.Longest Word With All Prefixes
1 parent a65226b commit d582d74

File tree

9 files changed

+749
-263
lines changed

9 files changed

+749
-263
lines changed

solution/1800-1899/1858.Longest Word With All Prefixes/README.md

Lines changed: 229 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@
5353

5454
**方法一:前缀树**
5555

56+
我们定义一棵前缀树,前缀树每个节点有两个属性,一个是长度为 $26$ 的子节点数组 `children`,另一个是是否为单词结尾的标记 `isEnd`
57+
58+
我们遍历 `words`,对于每个单词 `w`,我们从根节点开始遍历,如果当前节点的子节点数组中没有 `w` 的第一个字符,我们就创建一个新的节点,然后继续遍历 `w` 的下一个字符,直到遍历完 `w`,我们将当前节点的 `isEnd` 标记为 `true`
59+
60+
接下来我们遍历 `words`,对于每个单词 `w`,我们从根节点开始遍历,如果当前节点的子节点数组的 `isEnd` 字段为 `false`,说明 `w` 的某个前缀不在 `words` 中,我们返回 `false`。否则继续遍历 `w` 的下一个字符,直到遍历完 `w`,我们返回 `true`
61+
62+
时间复杂度 $O(\sum_{w \in words} |w|)$,空间复杂度 $O(\sum_{w \in words} |w|)$。
63+
5664
<!-- tabs:start -->
5765

5866
### **Python3**
@@ -61,20 +69,22 @@
6169

6270
```python
6371
class Trie:
72+
__slots__ = ["children", "is_end"]
73+
6474
def __init__(self):
65-
self.children = [None] * 26
66-
self.is_end = False
75+
self.children: List[Trie | None] = [None] * 26
76+
self.is_end: bool = False
6777

68-
def insert(self, w):
78+
def insert(self, w: str) -> None:
6979
node = self
7080
for c in w:
7181
idx = ord(c) - ord("a")
72-
if node.children[idx] is None:
82+
if not node.children[idx]:
7383
node.children[idx] = Trie()
7484
node = node.children[idx]
7585
node.is_end = True
7686

77-
def search(self, w):
87+
def search(self, w: str) -> bool:
7888
node = self
7989
for c in w:
8090
idx = ord(c) - ord("a")
@@ -91,9 +101,7 @@ class Solution:
91101
trie.insert(w)
92102
ans = ""
93103
for w in words:
94-
if ans and (len(ans) > len(w) or (len(ans) == len(w) and ans < w)):
95-
continue
96-
if trie.search(w):
104+
if (len(w) > len(ans) or len(w) == len(ans) and w < ans) and trie.search(w):
97105
ans = w
98106
return ans
99107
```
@@ -104,26 +112,29 @@ class Solution:
104112

105113
```java
106114
class Trie {
107-
Trie[] children = new Trie[26];
108-
boolean isEnd;
115+
private Trie[] children = new Trie[26];
116+
private boolean isEnd;
117+
118+
public Trie() {
119+
}
109120

110-
void insert(String w) {
121+
public void insert(String w) {
111122
Trie node = this;
112123
for (char c : w.toCharArray()) {
113-
c -= 'a';
114-
if (node.children[c] == null) {
115-
node.children[c] = new Trie();
124+
int idx = c - 'a';
125+
if (node.children[idx] == null) {
126+
node.children[idx] = new Trie();
116127
}
117-
node = node.children[c];
128+
node = node.children[idx];
118129
}
119130
node.isEnd = true;
120131
}
121132

122-
boolean search(String w) {
133+
public boolean search(String w) {
123134
Trie node = this;
124135
for (char c : w.toCharArray()) {
125-
c -= 'a';
126-
node = node.children[c];
136+
int idx = c - 'a';
137+
node = node.children[idx];
127138
if (!node.isEnd) {
128139
return false;
129140
}
@@ -140,12 +151,8 @@ class Solution {
140151
}
141152
String ans = "";
142153
for (String w : words) {
143-
if (!"".equals(ans)
144-
&& (ans.length() > w.length()
145-
|| (ans.length() == w.length() && ans.compareTo(w) < 0))) {
146-
continue;
147-
}
148-
if (trie.search(w)) {
154+
if ((w.length() > ans.length() || (w.length() == ans.length() && w.compareTo(ans) < 0))
155+
&& trie.search(w)) {
149156
ans = w;
150157
}
151158
}
@@ -159,30 +166,34 @@ class Solution {
159166
```cpp
160167
class Trie {
161168
private:
162-
vector<Trie*> children;
163-
bool isEnd;
169+
Trie* children[26];
170+
bool isEnd = false;
164171

165172
public:
166-
Trie()
167-
: children(26)
168-
, isEnd(false) {}
173+
Trie() {
174+
fill(begin(children), end(children), nullptr);
175+
}
169176

170-
void insert(string word) {
177+
void insert(const string& w) {
171178
Trie* node = this;
172-
for (char c : word) {
173-
c -= 'a';
174-
if (!node->children[c]) node->children[c] = new Trie();
175-
node = node->children[c];
179+
for (char c : w) {
180+
int idx = c - 'a';
181+
if (!node->children[idx]) {
182+
node->children[idx] = new Trie();
183+
}
184+
node = node->children[idx];
176185
}
177186
node->isEnd = true;
178187
}
179188

180-
bool search(string word) {
189+
bool search(const string& w) {
181190
Trie* node = this;
182-
for (char c : word) {
183-
c -= 'a';
184-
node = node->children[c];
185-
if (!node->isEnd) return false;
191+
for (char c : w) {
192+
int idx = c - 'a';
193+
node = node->children[idx];
194+
if (!node->isEnd) {
195+
return false;
196+
}
186197
}
187198
return true;
188199
}
@@ -191,12 +202,15 @@ public:
191202
class Solution {
192203
public:
193204
string longestWord(vector<string>& words) {
194-
Trie* trie = new Trie();
195-
for (auto w : words) trie->insert(w);
205+
Trie trie;
206+
for (const string& w : words) {
207+
trie.insert(w);
208+
}
196209
string ans = "";
197-
for (auto w : words) {
198-
if (ans != "" && (ans.size() > w.size() || (ans.size() == w.size() && ans < w))) continue;
199-
if (trie->search(w)) ans = w;
210+
for (const string& w : words) {
211+
if ((w.size() > ans.size() || (w.size() == ans.size() && w < ans)) && trie.search(w)) {
212+
ans = w;
213+
}
200214
}
201215
return ans;
202216
}
@@ -214,22 +228,24 @@ type Trie struct {
214228
func newTrie() *Trie {
215229
return &Trie{}
216230
}
217-
func (this *Trie) insert(word string) {
218-
node := this
219-
for _, c := range word {
220-
c -= 'a'
221-
if node.children[c] == nil {
222-
node.children[c] = newTrie()
231+
232+
func (t *Trie) insert(w string) {
233+
node := t
234+
for _, c := range w {
235+
idx := c - 'a'
236+
if node.children[idx] == nil {
237+
node.children[idx] = newTrie()
223238
}
224-
node = node.children[c]
239+
node = node.children[idx]
225240
}
226241
node.isEnd = true
227242
}
228-
func (this *Trie) search(word string) bool {
229-
node := this
230-
for _, c := range word {
231-
c -= 'a'
232-
node = node.children[c]
243+
244+
func (t *Trie) search(w string) bool {
245+
node := t
246+
for _, c := range w {
247+
idx := c - 'a'
248+
node = node.children[idx]
233249
if !node.isEnd {
234250
return false
235251
}
@@ -244,17 +260,170 @@ func longestWord(words []string) string {
244260
}
245261
ans := ""
246262
for _, w := range words {
247-
if ans != "" && (len(ans) > len(w) || (len(ans) == len(w) && ans < w)) {
248-
continue
249-
}
250-
if trie.search(w) {
263+
if (len(w) > len(ans) || (len(w) == len(ans) && w < ans)) && trie.search(w) {
251264
ans = w
252265
}
253266
}
254267
return ans
255268
}
256269
```
257270

271+
### **TypeScript**
272+
273+
```ts
274+
class Trie {
275+
private children: (Trie | null)[] = Array(26).fill(null);
276+
private isEnd: boolean = false;
277+
278+
insert(w: string): void {
279+
let node: Trie = this;
280+
for (const c of w) {
281+
const idx: number = c.charCodeAt(0) - 'a'.charCodeAt(0);
282+
if (!node.children[idx]) {
283+
node.children[idx] = new Trie();
284+
}
285+
node = node.children[idx] as Trie;
286+
}
287+
node.isEnd = true;
288+
}
289+
290+
search(w: string): boolean {
291+
let node: Trie = this;
292+
for (const c of w) {
293+
const idx: number = c.charCodeAt(0) - 'a'.charCodeAt(0);
294+
node = node.children[idx] as Trie;
295+
if (!node.isEnd) {
296+
return false;
297+
}
298+
}
299+
return true;
300+
}
301+
}
302+
303+
function longestWord(words: string[]): string {
304+
const trie: Trie = new Trie();
305+
for (const w of words) {
306+
trie.insert(w);
307+
}
308+
let ans: string = '';
309+
for (const w of words) {
310+
if ((w.length > ans.length || (w.length === ans.length && w < ans)) && trie.search(w)) {
311+
ans = w;
312+
}
313+
}
314+
return ans;
315+
}
316+
```
317+
318+
### **Rust**
319+
320+
```rust
321+
struct Trie {
322+
children: [Option<Box<Trie>>; 26],
323+
is_end: bool,
324+
}
325+
326+
impl Trie {
327+
fn new() -> Self {
328+
Trie {
329+
children: Default::default(),
330+
is_end: false,
331+
}
332+
}
333+
334+
fn insert(&mut self, w: &str) {
335+
let mut node = self;
336+
for c in w.chars() {
337+
let idx = (c as usize) - ('a' as usize);
338+
node = node.children[idx].get_or_insert_with(|| Box::new(Trie::new()));
339+
}
340+
node.is_end = true;
341+
}
342+
343+
fn search(&self, w: &str) -> bool {
344+
let mut node = self;
345+
for c in w.chars() {
346+
let idx = (c as usize) - ('a' as usize);
347+
if let Some(next_node) = &node.children[idx] {
348+
node = next_node.as_ref();
349+
if !node.is_end {
350+
return false;
351+
}
352+
}
353+
}
354+
true
355+
}
356+
}
357+
358+
impl Solution {
359+
pub fn longest_word(words: Vec<String>) -> String {
360+
let mut trie = Trie::new();
361+
for w in &words {
362+
trie.insert(w);
363+
}
364+
let mut ans = String::new();
365+
for w in &words {
366+
if (w.len() > ans.len() || (w.len() == ans.len() && w < &ans)) && trie.search(w) {
367+
ans = w.clone();
368+
}
369+
}
370+
ans
371+
}
372+
}
373+
```
374+
375+
### **C#**
376+
377+
```cs
378+
public class Trie {
379+
private Trie[] children = new Trie[26];
380+
private bool isEnd;
381+
382+
public Trie() { }
383+
384+
public void Insert(string w) {
385+
Trie node = this;
386+
foreach (char c in w.ToCharArray()) {
387+
int idx = c - 'a';
388+
if (node.children[idx] == null) {
389+
node.children[idx] = new Trie();
390+
}
391+
node = node.children[idx];
392+
}
393+
node.isEnd = true;
394+
}
395+
396+
public bool Search(string w) {
397+
Trie node = this;
398+
foreach (char c in w.ToCharArray()) {
399+
int idx = c - 'a';
400+
node = node.children[idx];
401+
if (!node.isEnd) {
402+
return false;
403+
}
404+
}
405+
return true;
406+
}
407+
}
408+
409+
public class Solution {
410+
public string LongestWord(string[] words) {
411+
Trie trie = new Trie();
412+
foreach (string w in words) {
413+
trie.Insert(w);
414+
}
415+
416+
string ans = "";
417+
foreach (string w in words) {
418+
if ((w.Length > ans.Length || (w.Length == ans.Length && string.Compare(w, ans) < 0)) && trie.Search(w)) {
419+
ans = w;
420+
}
421+
}
422+
return ans;
423+
}
424+
}
425+
```
426+
258427
### **...**
259428

260429
```

0 commit comments

Comments
 (0)