Skip to content

Commit fbcb585

Browse files
committed
feat(algoritms, datastructures): trie data structure, longest word with prefixes
1 parent 6ba34ca commit fbcb585

14 files changed

Lines changed: 197 additions & 0 deletions

algorithms/trie/__init__.py

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Longest Word With All Prefixes
2+
3+
You are given an array of strings, words. Your task is to find the longest string in words such that every prefix of
4+
this string is also present in words.
5+
6+
A prefix of a string is any leading substring. For example, the prefixes of "apple" are "a", "ap", "app", and "appl".
7+
8+
1. If multiple valid strings have the same maximum length, return the lexicographically smallest one.
9+
2. If no such string exists, return an empty string "".
10+
11+
12+
## Constraints:
13+
14+
- 1 ≤ `words.length` ≤ 10^3
15+
- 1 ≤ `words[i].length` ≤ 10^3
16+
- 1 ≤ `sum(words[i].length)` ≤ 10^3
17+
- `words[i]` consists only of lowercase English letters.
18+
19+
## Examples
20+
21+
![Example 1](./images/examples/longest_word_with_prefixes_example_1.png)
22+
![Example 2](./images/examples/longest_word_with_prefixes_example_2.png)
23+
![Example 3](./images/examples/longest_word_with_prefixes_example_3.png)
24+
![Example 4](./images/examples/longest_word_with_prefixes_example_4.png)
25+
![Example 5](./images/examples/longest_word_with_prefixes_example_5.png)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import List
2+
from datastructures.trees.trie import TrieNode
3+
4+
5+
def longest_word(words: List[str]) -> str:
6+
"""
7+
Find the longest string in words such that every prefix of this string is also present in words.
8+
9+
Time complexity
10+
Building the trie and validating all words takes O(∑∣wordi∣).
11+
12+
Space complexity
13+
The trie stores, at most, one node per character, so the space is O(∑∣wordi∣)
14+
15+
Args:
16+
words (List[str]): list of words
17+
Returns:
18+
str: longest word
19+
"""
20+
if not words:
21+
return ""
22+
23+
trie = TrieNode()
24+
25+
for idx, word in enumerate(words):
26+
trie.insert(word, idx)
27+
28+
result = ""
29+
for word in words:
30+
word_length = len(word)
31+
result_length = len(result)
32+
33+
is_longer = word_length > result_length
34+
is_same_length_but_smaller = word_length == result_length and word < result
35+
36+
if (is_longer or is_same_length_but_smaller) and trie.search(word):
37+
result = word
38+
39+
return result
310 KB
Loading
261 KB
Loading
288 KB
Loading
275 KB
Loading
294 KB
Loading
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import unittest
2+
from typing import List
3+
from parameterized import parameterized
4+
from algorithms.trie.longest_word_with_prefixes import longest_word
5+
6+
LONGEST_WORD_WITH_PREFIXES_TEST_CASES = [
7+
(["a", "ab", "abc", "abd", "abde"], "abde"),
8+
(["x", "xy", "xyz", "xz"], "xyz"),
9+
(["m", "ma", "man", "many", "mat"], "many"),
10+
(["dog", "do", "d", "cat"], "dog"),
11+
(["car", "ca", "c", "cat"], "car"),
12+
(["a", "ap", "app", "apple", "apply"], "app"),
13+
]
14+
15+
16+
class LongestWordWithPrefixesTestCase(unittest.TestCase):
17+
@parameterized.expand(LONGEST_WORD_WITH_PREFIXES_TEST_CASES)
18+
def test_longest_word_with_prefixes(self, words: List[str], expected: str):
19+
actual = longest_word(words)
20+
self.assertEqual(expected, actual)
21+
22+
23+
if __name__ == "__main__":
24+
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Bloom Filter
2+
3+
An implementation of a bloom filter data structure.

0 commit comments

Comments
 (0)