2185. Counting Words With a Given Prefix - Explanation
Description
You are given an array of strings words and a string pref.
Return the number of strings in words that contain pref as a prefix.
A prefix of a string s is any leading contiguous substring of s.
Example 1:
Input: words = ["pay","attention","practice","attend"], pref = "at"
Output: 2Explanation: The two strings that contain "at" as a prefix are: "attention" and "attend".
Example 2:
Input: words = ["neetcode","neet","nee","code"], pref = "ne"
Output: 3Explanation: The three strings that contain "ne" as a prefix are: "neetcode","neet" and "nee".
Constraints:
1 <= words.length <= 1001 <= words[i].length, pref.length <= 100words[i]andprefconsist of lowercase English letters.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- String Manipulation - Comparing characters and understanding prefix matching operations
- Trie (Prefix Tree) - A tree-based data structure for efficient prefix storage and lookup
- Array/List Traversal - Iterating through collections of strings
1. Brute Force
Intuition
To check if a word has a given prefix, we compare the first few characters of the word with the prefix string. If the word is shorter than the prefix, it cannot have that prefix. Otherwise, we check character by character until we either find a mismatch or confirm all prefix characters match.
Algorithm
- Initialize a counter to
0. - For each word in the array:
- Skip if the word is shorter than the prefix length.
- Compare each character of the word with the corresponding character of the prefix.
- If all characters match, increment the counter.
- Return the final count.
Time & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of words and is the length of the string .
2. Built-In Method
Intuition
Most programming languages provide built-in methods to check if a string starts with a given prefix. These methods handle the character comparison internally and are optimized for the task, making the code cleaner and less error-prone.
Algorithm
- Initialize a counter to
0. - For each word in the array, use the language's built-in prefix checking method (like
startsWithorhasPrefix). - If the word starts with the prefix, increment the counter.
- Return the final count.
Time & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of words and is the length of the string .
3. Trie
Intuition
A Trie (prefix tree) is a tree structure where each node represents a character. By inserting only the first few characters of each word (up to the prefix length), we build a compact structure. Each node keeps a count of how many words pass through it. After inserting all words, we traverse the trie following the prefix characters and return the count at the final node.
Algorithm
- Create a Trie data structure where each node has children and a count.
- For each word in the array:
- If the word is at least as long as the prefix, insert the first
prefix.lengthcharacters into the trie. - Increment the count at each node during insertion.
- If the word is at least as long as the prefix, insert the first
- Traverse the trie following the prefix characters.
- If any character is missing, return
0. - Otherwise, return the count at the final node.
class PrefixNode:
def __init__(self):
self.children = {} # a -> PrefixNode
self.count = 0
class PrefixTree:
def __init__(self):
self.root = PrefixNode()
def add(self, w: str, length: int) -> None:
cur = self.root
for i in range(length):
if w[i] not in cur.children:
cur.children[w[i]] = PrefixNode()
cur = cur.children[w[i]]
cur.count += 1
def count(self, pref: str) -> int:
cur = self.root
for c in pref:
if c not in cur.children:
return 0
cur = cur.children[c]
return cur.count
class Solution:
def prefixCount(self, words: List[str], pref: str) -> int:
prefix_tree = PrefixTree()
for w in words:
if len(w) >= len(pref):
prefix_tree.add(w, len(pref))
return prefix_tree.count(pref)Time & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of words, is the length of the string and is the maximum length of a word.
Common Pitfalls
Checking Contains Instead of Starts With
The problem asks for words that start with the prefix, not words that contain the prefix anywhere. Using a contains/includes check instead of a starts-with check will incorrectly count words where the prefix appears in the middle.
# Wrong: Checks if prefix exists anywhere in the word
if pref in word:
count += 1
# Correct: Checks if word starts with prefix
if word.startswith(pref):
count += 1Not Handling Words Shorter Than the Prefix
When manually comparing characters, forgetting to check if the word is at least as long as the prefix leads to index out of bounds errors or incorrect matches.
# Wrong: May cause index error if word is shorter than prefix
for i in range(len(pref)):
if word[i] != pref[i]: # Error when len(word) < len(pref)
break
# Correct: Skip words shorter than the prefix
if len(word) < len(pref):
continue
for i in range(len(pref)):
if word[i] != pref[i]:
break
Sign in to join the discussion