Skip to content

Commit 177631d

Browse files
committed
Counting words with a given prefix
1 parent 49fe30a commit 177631d

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# 2185. Counting words with a given prefix
2+
# Topics: 'Array', 'String', 'String Matching'
3+
4+
# You are given an array of strings words and a string pref.
5+
6+
# Return the number of strings in words that contain pref as a prefix.
7+
8+
# A prefix of a string s is any leading contiguous substring of s.
9+
10+
11+
12+
# Example 1:
13+
14+
# Input: words = ["pay","attention","practice","attend"], pref = "at"
15+
# Output: 2
16+
# Explanation: The 2 strings that contain "at" as a prefix are: "attention" and "attend".
17+
18+
# Example 2:
19+
20+
# Input: words = ["leetcode","win","loops","success"], pref = "code"
21+
# Output: 0
22+
# Explanation: There are no strings that contain "code" as a prefix.
23+
24+
25+
26+
# Constraints:
27+
28+
# 1 <= words.length <= 100
29+
# 1 <= words[i].length, pref.length <= 100
30+
# words[i] and pref consist of lowercase English letters.
31+
32+
from typing import List
33+
34+
class Node:
35+
def __init__(self):
36+
self.children = {}
37+
self.times = 1
38+
39+
class Trie:
40+
def __init__(self):
41+
self.root = Node()
42+
43+
def insert(self, word: str, length: int):
44+
cur = self.root
45+
for i in range (length):
46+
if word[i] not in cur.children:
47+
cur.children[word[i]] = Node()
48+
else:
49+
cur.children[word[i]].times += 1
50+
cur = cur.children[word[i]]
51+
52+
def prefix(self, pref: str) -> int:
53+
cur = self.root
54+
for char in pref:
55+
if char not in cur.children:
56+
return 0
57+
cur = cur.children[char]
58+
return cur.times
59+
60+
class Solution:
61+
def prefixCount(self, words: List[str], pref: str) -> int:
62+
trie = Trie()
63+
for word in words:
64+
if len(word) >= len(pref):
65+
trie.insert(word, len(pref))
66+
return trie.prefix(pref)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import unittest
2+
from prefix import Solution
3+
4+
class TestPrefixCount(unittest.TestCase):
5+
def setUp(self):
6+
self.sol = Solution()
7+
8+
def test_example1(self):
9+
words = ["pay", "attention", "practice", "attend"]
10+
pref = "at"
11+
self.assertEqual(self.sol.prefixCount(words, pref), 2)
12+
13+
def test_example2(self):
14+
words = ["leetcode", "win", "loops", "success"]
15+
pref = "code"
16+
self.assertEqual(self.sol.prefixCount(words, pref), 0)
17+
18+
def test_single_match(self):
19+
words = ["apple", "apricot", "banana"]
20+
pref = "app"
21+
self.assertEqual(self.sol.prefixCount(words, pref), 1)
22+
23+
def test_all_match(self):
24+
words = ["a", "ab", "abc", "abcd"]
25+
pref = "a"
26+
self.assertEqual(self.sol.prefixCount(words, pref), 4)
27+
28+
def test_no_match(self):
29+
words = ["cat", "dog", "fish"]
30+
pref = "z"
31+
self.assertEqual(self.sol.prefixCount(words, pref), 0)
32+
33+
def test_prefix_longer_than_words(self):
34+
words = ["hi", "hello"]
35+
pref = "hello!"
36+
self.assertEqual(self.sol.prefixCount(words, pref), 0)
37+
38+
def test_duplicate_words(self):
39+
words = ["at", "at", "attention"]
40+
pref = "at"
41+
self.assertEqual(self.sol.prefixCount(words, pref), 3)
42+
43+
def test_empty_list(self):
44+
words = []
45+
pref = "any"
46+
self.assertEqual(self.sol.prefixCount(words, pref), 0)
47+
48+
def test_single_letter_prefix(self):
49+
words = ["x", "xy", "xyz", "yy"]
50+
pref = "x"
51+
self.assertEqual(self.sol.prefixCount(words, pref), 3)
52+
53+
54+
if __name__ == "__main__":
55+
unittest.main()

0 commit comments

Comments
 (0)