3045. Count Prefix and Suffix Pairs II
Description
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)returnstrueifstr1is both a and a ofstr2, andfalseotherwise.
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
Explanation: 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: 2
Explanation: 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. Example 3:
Input: words = ["abab","ab"]
Output: 0
Explanation: In this example, the only valid index pair is i = 0 and j = 1, and isPrefixAndSuffix("abab", "ab") is false.
Therefore, the answer is 0.
Constraints:
1 <= words.length <= 1051 <= words[i].length <= 105words[i]consists only of lowercase English letters.- The sum of the lengths of all
words[i]does not exceed5 * 105.
Solutions
Solution: Trie
- Time complexity: O(n)
- Space complexity: O(n)
JavaScript
js
/**
* @param {string[]} words
* @return {number}
*/
const countPrefixSuffixPairs = function (words) {
const trie = new Trie();
let result = 0;
for (const word of words) {
result += trie.insert(word);
}
return result;
};
class TrieNode {
constructor() {
this.children = new Map();
this.count = 0;
}
}
class Trie {
#BASE_CODE = 'a'.charCodeAt(0);
constructor() {
this.root = new TrieNode();
}
insert(word) {
const n = word.length;
let count = 0;
let node = this.root;
for (let index = 0; index < n; index++) {
const prefix = word[index].charCodeAt(0) - this.#BASE_CODE;
const suffix = word[n - index - 1].charCodeAt(0) - this.#BASE_CODE;
const hash = prefix * 26 + suffix;
if (!node.children.has(hash)) {
node.children.set(hash, new TrieNode());
}
node = node.children.get(hash);
count += node.count;
}
node.count += 1;
return count;
}
}