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
.
For example:
words = ["a","aba","ababa","aa"]
Output: 4
Explanation:
The counted index pairs are:
i = 0 and j = 1 because isPrefixAndSuffix("a", "aba") is true. i = 0 and j = 2 because isPrefixAndSuffix("a", "ababa") is true. i = 0 and j = 3 because isPrefixAndSuffix("a", "aa") is true. i = 1 and j = 2 because isPrefixAndSuffix("aba", "ababa") is true.
Therefore, the answer is 4.
Write a function to solve this problem. What is the time and space complexity?
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 approach to counting prefix and suffix pairs involves checking every possible pair of words in the given list. For each pair, we'll determine if the first word is both a prefix of the second and a suffix of the second.
Here's how the algorithm would work step-by-step:
def count_prefix_suffix_pairs_brute_force(words):
pair_count = 0
number_of_words = len(words)
for first_word_index in range(number_of_words):
for second_word_index in range(number_of_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
if second_word.startswith(first_word):
# Check if the first word is a suffix of the second word
if second_word.endswith(first_word):
pair_count += 1
return pair_count
The optimal approach focuses on efficiently determining pairs of words where one is both a prefix and suffix of the other. We avoid unnecessary comparisons by pre-calculating and storing the frequency of each word. This allows us to quickly identify and count matching prefix-suffix pairs.
Here's how the algorithm would work step-by-step:
def count_prefix_suffix_pairs(words):
word_counts = {}
for word in words:
word_counts[word] = word_counts.get(word, 0) + 1
total_pairs = 0
for current_word in words:
for shorter_word in word_counts:
# Only compare against shorter words
if len(shorter_word) <= len(current_word):
if current_word.startswith(shorter_word) and current_word.endswith(shorter_word):
total_pairs += word_counts[shorter_word]
# Adjust count if a word is both prefix and suffix of itself.
for word, count in word_counts.items():
if count > 1:
total_pairs += count * (count - 1) // 2
return total_pairs
Case | How to Handle |
---|---|
Empty input array | Return 0 since there are no prefix/suffix pairs. |
Array with a single string | Return 0 since a pair requires two strings. |
Very large input array (N > 100) to test for time complexity issues | Ensure algorithm is O(N^2) or better, avoiding brute-force comparison. |
Strings of very large length to check for string comparison efficiency | Utilize efficient string comparison methods to avoid performance bottlenecks. |
All strings in the input array are identical | The algorithm should correctly count all valid pairs without overcounting. |
Strings are prefixes or suffixes of each other, but not equal | The prefix and suffix checks must be accurate to identify genuine pairs. |
Strings containing special characters or Unicode | Ensure the comparison function correctly handles all character types. |
Strings are empty strings | Carefully handle comparisons involving empty strings to avoid unexpected behavior. |