Skip to content

Commit 220264f

Browse files
committed
update
1 parent 8664e13 commit 220264f

12 files changed

+453
-24
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ Pattern500 is inspired by Blind 75 and Grind 75's classic problem selection. Pat
199199
| 185 | | [6. Zigzag Conversion](https://leetcode.com/problems/zigzag-conversion/) | [F]string | string composition | [Python]([F]string/[F]string/6-zigzag-conversion.py) |
200200
| 186 | | [trie]([G]trie/trie.md) | [G]trie | | |
201201
| 187 | O | [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) | [G]trie | standard trie | [Python]([G]trie/[G]trie/208-implement-trie-prefix-tree.py) |
202-
| 188 | O | [XX]() | [X]XX | XX | [Python]() |
203-
| 189 | O | [XX]() | [X]XX | XX | [Python]() |
204-
| 190 | O | [XX]() | [X]XX | XX | [Python]() |
205-
| 191 | O | [XX]() | [X]XX | XX | [Python]() |
206-
| 192 | O | [XX]() | [X]XX | XX | [Python]() |
207-
| 193 | O | [XX]() | [X]XX | XX | [Python]() |
208-
| 194 | O | [XX]() | [X]XX | XX | [Python]() |
209-
| 195 | O | [XX]() | [X]XX | XX | [Python]() |
210-
| 196 | O | [XX]() | [X]XX | XX | [Python]() |
202+
| 188 | O | [588. Design In-Memory File System](https://leetcode.com/problems/design-in-memory-file-system/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/588-design-in-memory-file-system.py) |
203+
| 189 | | [1268. Search Suggestions System](https://leetcode.com/problems/search-suggestions-system/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/1268-search-suggestions-system.py) |
204+
| 190 | | [2185. Counting Words With a Given Prefix](https://leetcode.com/problems/counting-words-with-a-given-prefix/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/2185-counting-words-with-a-given-prefix.py) |
205+
| 191 | | [2416. Sum of Prefix Scores of Strings](https://leetcode.com/problems/sum-of-prefix-scores-of-strings/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/2416-sum-of-prefix-scores-of-strings.py) |
206+
| 192 | | [745. Prefix and Suffix Search](https://leetcode.com/problems/prefix-and-suffix-search/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/745-prefix-and-suffix-search.py) |
207+
| 193 | | [1166. Design File System](https://leetcode.com/problems/design-file-system/) | [G]trie | custom trie node | [Python]([G]trie/[G]trie/1166-design-file-system.py) |
208+
| 194 | O | [211. Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | [G]trie | perform dfs inside trie | [Python]([G]trie/[G]trie/211-design-add-and-search-words-data-structure.py) |
209+
| 195 | | [472. Concatenated Words](https://leetcode.com/problems/concatenated-words/) | [G]trie | perform dfs inside trie | [Python]([G]trie/[G]trie/472-concatenated-words.py) |
210+
| 196 | | [642. Design Search Autocomplete System](https://leetcode.com/problems/design-search-autocomplete-system/) | [G]trie | perform dfs inside trie | [Python]([G]trie/[G]trie/642-design-search-autocomplete-system.py) |
211211
| 197 | | [array]([H]array/array.md) | [H]array | | |
212212
| 198 | O | [XX]() | [X]XX | XX | [Python]() |
213213
| 199 | O | [XX]() | [X]XX | XX | [Python]() |
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.val = - 1
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, path, val):
11+
path = path.split('/')[1:]
12+
node = self.root
13+
for i, p in enumerate(path):
14+
if p not in node.children:
15+
if i == len(path) - 1:
16+
node.children[p] = TrieNode()
17+
else:
18+
return False
19+
node = node.children[p]
20+
if node.val == - 1:
21+
node.val = val
22+
return True
23+
else:
24+
return False
25+
26+
def search(self, path):
27+
path = path.split('/')[1:]
28+
node = self.root
29+
for p in path:
30+
if p not in node.children:
31+
return - 1
32+
node = node.children[p]
33+
return node.val
34+
35+
class FileSystem:
36+
def __init__(self):
37+
self.trie = Trie()
38+
39+
def createPath(self, path: str, value: int) -> bool:
40+
return self.trie.insert(path, value)
41+
42+
def get(self, path: str) -> int:
43+
return self.trie.search(path)
44+
45+
# Your FileSystem object will be instantiated and called as such:
46+
# obj = FileSystem()
47+
# param_1 = obj.createPath(path,value)
48+
# param_2 = obj.get(path)
49+
50+
# time O(1) for init, O(L) for createPath() and get()
51+
# space O(nL)
52+
# using trie and custom trie node
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.suggests = []
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, s):
11+
node = self.root
12+
for c in s:
13+
if c not in node.children:
14+
node.children[c] = TrieNode()
15+
node = node.children[c]
16+
node.suggests.append(s)
17+
node.suggests = sorted(node.suggests)[:3]
18+
19+
def search(self, s):
20+
res = []
21+
node = self.root
22+
for i, c in enumerate(s):
23+
if c not in node.children:
24+
res.extend([[] for _ in range(len(s) - i)])
25+
break
26+
node = node.children[c]
27+
res.append(node.suggests)
28+
return res
29+
30+
class Solution:
31+
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
32+
trie = Trie()
33+
for p in products:
34+
trie.insert(p)
35+
return trie.search(searchWord)
36+
37+
# time O(nL)
38+
# space O(nL), nL nodes in trie, not counting suggests list storage in node
39+
# using trie and custom trie node and sort

[G]trie/[G]trie/208-implement-trie-prefix-tree.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
class TrieNode:
22
def __init__(self):
33
self.children = {}
4-
self.isWord = False
4+
self.is_word = False
55

66
class Trie:
7-
87
def __init__(self):
98
self.root = TrieNode()
109

@@ -14,15 +13,15 @@ def insert(self, word: str) -> None:
1413
if c not in node.children:
1514
node.children[c] = TrieNode()
1615
node = node.children[c]
17-
node.isWord = True
16+
node.is_word = True
1817

1918
def search(self, word: str) -> bool:
2019
node = self.root
2120
for c in word:
2221
if c not in node.children:
2322
return False
2423
node = node.children[c]
25-
return node.isWord
24+
return node.is_word
2625

2726
def startsWith(self, prefix: str) -> bool:
2827
node = self.root
@@ -31,7 +30,7 @@ def startsWith(self, prefix: str) -> bool:
3130
return False
3231
node = node.children[c]
3332
return True
34-
33+
3534
# Your Trie object will be instantiated and called as such:
3635
# obj = Trie()
3736
# obj.insert(word)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.is_word = False
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, s):
11+
node = self.root
12+
for c in s:
13+
if c not in node.children:
14+
node.children[c] = TrieNode()
15+
node = node.children[c]
16+
node.is_word = True
17+
18+
def search(self, s):
19+
return self.search_helper(s, self.root, 0)
20+
21+
def search_helper(self, s, node, idx):
22+
for i in range(idx, len(s)):
23+
if s[i] == '.':
24+
for child in node.children.values():
25+
if self.search_helper(s, child, i + 1):
26+
return True
27+
return False
28+
if s[i] not in node.children:
29+
return False
30+
node = node.children[s[i]]
31+
return node.is_word
32+
33+
class WordDictionary:
34+
def __init__(self):
35+
self.trie = Trie()
36+
self.len_set = set()
37+
38+
def addWord(self, word: str) -> None:
39+
self.len_set.add(len(word))
40+
self.trie.insert(word)
41+
42+
def search(self, word: str) -> bool:
43+
if len(word) not in self.len_set:
44+
return False
45+
return self.trie.search(word)
46+
47+
# Your WordDictionary object will be instantiated and called as such:
48+
# obj = WordDictionary()
49+
# obj.addWord(word)
50+
# param_2 = obj.search(word)
51+
52+
# time O(nL or 26**L) for search(), O(L) for addWord()
53+
# space O(nL), n is the number of words, L is the max len
54+
# using trie and perform dfs inside trie and prune
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.count = 0
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, s):
11+
node = self.root
12+
for c in s:
13+
if c not in node.children:
14+
node.children[c] = TrieNode()
15+
node = node.children[c]
16+
node.count += 1
17+
18+
def search(self, s):
19+
node = self.root
20+
for c in s:
21+
if c not in node.children:
22+
return 0
23+
node = node.children[c]
24+
return node.count
25+
26+
class Solution:
27+
def prefixCount(self, words: List[str], pref: str) -> int:
28+
trie = Trie()
29+
for w in words:
30+
trie.insert(w)
31+
return trie.search(pref)
32+
33+
# time O(nL)
34+
# space O(nL)
35+
# using trie and custom trie node
36+
'''
37+
1. using trie allows we change requested prefix frequently
38+
2. if prefix is fixed, and words are sorted. try binary search (O(klogn)))
39+
'''
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.count = 0
5+
self.length = 0
6+
7+
class Trie:
8+
def __init__(self):
9+
self.root = TrieNode()
10+
11+
def insert(self, s):
12+
node = self.root
13+
for i, c in enumerate(s):
14+
if c not in node.children:
15+
node.children[c] = TrieNode()
16+
node = node.children[c]
17+
node.count += 1
18+
node.length = i + 1
19+
20+
def search(self, s):
21+
res = 0
22+
node = self.root
23+
for c in s:
24+
node = node.children[c]
25+
res += node.count
26+
if node.count == 1:
27+
res += len(s) - node.length
28+
break
29+
return res
30+
31+
class Solution:
32+
def sumPrefixScores(self, words: List[str]) -> List[int]:
33+
trie = Trie()
34+
for w in words:
35+
trie.insert(w)
36+
res = []
37+
for w in words:
38+
res.append(trie.search(w))
39+
return res
40+
41+
# time O(nL)
42+
# space O(nL)
43+
# using trie and custom trie node and prune
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.is_word = False
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, s):
11+
node = self.root
12+
for c in s:
13+
if c not in node.children:
14+
node.children[c] = TrieNode()
15+
node = node.children[c]
16+
node.is_word = True
17+
18+
def search(self, s):
19+
return self.search_helper(s, self.root, 0)
20+
21+
def search_helper(self, s, node, idx):
22+
for i in range(idx, len(s)):
23+
if node.is_word:
24+
if self.search_helper(s, self.root, i):
25+
return True
26+
if s[i] not in node.children:
27+
return False
28+
node = node.children[s[i]]
29+
return node.is_word
30+
31+
class Solution:
32+
def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:
33+
res = []
34+
trie = Trie()
35+
words.sort(key=len)
36+
for w in words:
37+
if trie.search(w):
38+
res.append(w)
39+
else:
40+
trie.insert(w)
41+
42+
return res
43+
44+
# time O(nlogn + nL + n * L**2), search is O(L**2) here not O(2**L), due to cost is L + L-1 + L-2 + ... + 1
45+
# space O(nL), n is the number of words, L is the max len
46+
# using trie and perform dfs inside trie and sort
47+
'''
48+
1. long word can only be consisted from short words, so we sort at first
49+
2. if certain word can be consisted from short words then no need to add in trie
50+
'''

0 commit comments

Comments
 (0)