You are given a 0-indexed string array words
.
Let's define a boolean function isPrefixAndSuffix
that takes two strings, str1
and str2
:
isPrefixAndSuffix(str1, str2)
returns true
if str1
is both a prefix and a suffix of str2
, and false
otherwise.For example, isPrefixAndSuffix("aba", "ababa")
is true
because "aba"
is a prefix of "ababa"
and also a suffix, but isPrefixAndSuffix("abc", "abcd")
is false
.
Return an integer denoting the number of index pairs (i, j)
such that i < j
, and isPrefixAndSuffix(words[i], words[j])
is true
.
Example 1:
Input: words = ["a","aba","ababa","aa"]
Output: 4
Example 2:
Input: words = ["pa","papa","ma","mama"]
Output: 2
Example 3:
Input: words = ["abab","ab"]
Output: 0
Write a function to solve this problem.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force strategy involves checking every possible pair of words to see if they fit the specified criteria. We will compare each word to every other word in the list. If a pair of words meets the criteria, we increment a counter.
Here's how the algorithm would work step-by-step:
def count_prefix_suffix_pairs_brute_force(words):
total_valid_pairs = 0
for first_word_index in range(len(words)):
for second_word_index in range(len(words)):
first_word = words[first_word_index]
second_word = words[second_word_index]
# Check if the first word is a prefix of the second word
is_prefix = second_word.startswith(first_word)
# Check if the first word is a suffix of the second word
is_suffix = second_word.endswith(first_word)
# Only count pairs where first is both a prefix and suffix of the second
if is_prefix and is_suffix:
total_valid_pairs += 1
return total_valid_pairs
The goal is to efficiently count matching prefix and suffix pairs within a large set of words. Instead of directly comparing every word with every other word, we use a Trie data structure to quickly identify potential matches based on prefixes and suffixes.
Here's how the algorithm would work step-by-step:
class TrieNode:
def __init__(self):
self.children = {}
self.count = 0
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for character in word:
if character not in node.children:
node.children[character] = TrieNode()
node = node.children[character]
node.count += 1
def count_words_with_prefix(self, word):
node = self.root
for character in word:
if character not in node.children:
return 0
node = node.children[character]
return node.count
def count_prefix_suffix_pairs(words):
trie = Trie()
for word in words:
trie.insert(word)
trie.insert(word[::-1])
total_pairs = 0
for word in words:
prefix_count = trie.count_words_with_prefix(word)
suffix_count = trie.count_words_with_prefix(word[::-1])
# This avoids overcounting pairs.
if word == word[::-1]:
total_pairs += (prefix_count + suffix_count - 1)
else:
total_pairs += (prefix_count + suffix_count)
# Divide by two because we inserted the words twice (forward and reversed).
return total_pairs // 2
Case | How to Handle |
---|---|
Empty words array | Return 0 since no pairs are possible. |
Words array with only one element | Return 0 since a pair requires at least two elements. |
All words in the array are identical | The solution must correctly count all possible pairs (i, j) where i != j given all words are equal. |
Long strings within words array | The solution's prefix/suffix check must handle long strings efficiently, potentially using early termination if a mismatch is found early. |
Words array with a single character string | The solution must handle the special case where a single character string could be both a prefix and suffix to other strings, and needs to avoid integer overflow. |
Maximum array size constraints are hit and the solution has O(N^2) complexity | Consider utilizing Tries/Prefix Trees or Hash Maps for better time complexity such as O(N*K) where K is the average length of the strings. |
Words containing unicode characters | Ensure string comparison handles Unicode correctly depending on the underlying language's string implementation. |
The same prefix/suffix string exists multiple times | Use hash map to count the frequencies of prefixes and suffixes, and calculate the number of valid pairs based on these frequencies. |