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: 4Explanation: In this example, 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.
Example 2:
Input: words = ["pa","papa","ma","mama"]
Output: 2Explanation: In this example, the counted index pairs are:
i = 0 and j = 1 because isPrefixAndSuffix("pa", "papa") is true.
i = 2 and j = 3 because isPrefixAndSuffix("ma", "mama") is true.
Therefore, the answer is 2.
Constraints:
1 <= words.length <= 501 <= words[i].length <= 10words[i] consists only of lowercase English letters.Before attempting this problem, you should be comfortable with:
For each pair of indices (i, j) where i < j, we need to check if words[i] is both a prefix and suffix of words[j]. We compare characters at the beginning and end of words[j] with words[i].
s1 is both a prefix and suffix of s2.s1 is not longer than s2.s1 character by character with the start of s2 (prefix check).s1 character by character with the end of s2 (suffix check).(i, j) with i < j and count valid prefix-suffix pairs.class Solution:
def countPrefixSuffixPairs(self, words: List[str]) -> int:
def isPrefixAndSuffix(s1, s2):
if len(s1) > len(s2):
return False
for i in range(len(s1)):
if s1[i] != s2[i]:
return False
j = 0
for i in range(len(s2) - len(s1), len(s2)):
if s1[j] != s2[i]:
return False
j += 1
return True
res = 0
for i in range(len(words)):
for j in range(i + 1, len(words)):
res += isPrefixAndSuffix(words[i], words[j])
return resWhere is the size of the input array , and is the maximum length of a string.
Most programming languages provide built-in methods to check if a string starts with or ends with another string. We can use these to simplify the prefix and suffix checks.
(i, j) where i < j.words[j] starts with words[i] using the built-in prefix check.words[j] ends with words[i] using the built-in suffix check.true, increment the result counter.Where is the size of the input array , and is the maximum length of a string.
We can use a trie where each node is keyed by a pair of characters: one from the prefix and one from the suffix. By processing words in reverse order and storing them in this combined trie, when we look up a word, we find how many previously seen words have it as both prefix and suffix.
class TrieNode:
def __init__(self):
self.children = {}
self.count = 0
class Trie:
def __init__(self):
self.root = TrieNode()
def add(self, w: str) -> None:
cur = self.root
for c1, c2 in zip(w, reversed(w)):
if (c1, c2) not in cur.children:
cur.children[(c1, c2)] = TrieNode()
cur = cur.children[(c1, c2)]
cur.count += 1
def count(self, w: str) -> int:
cur = self.root
for c1, c2 in zip(w, reversed(w)):
if (c1, c2) not in cur.children:
return 0
cur = cur.children[(c1, c2)]
return cur.count
class Solution:
def countPrefixSuffixPairs(self, words: List[str]) -> int:
res = 0
root = Trie()
for w in reversed(words):
res += root.count(w)
root.add(w)
return resWhere is the size of the input array , and is the maximum length of a string.
The condition requires words[i] to be BOTH a prefix AND a suffix of words[j]. Checking only one condition will give incorrect results.
# Wrong: only checks prefix
if w2.startswith(w1):
res += 1
# Correct: checks both conditions
if w2.startswith(w1) and w2.endswith(w1):
res += 1A string cannot be a prefix or suffix of a shorter string. Failing to check len(s1) <= len(s2) before comparing can lead to index out of bounds errors or false positives.