2416. Sum of Prefix Scores of Strings
Description
You are given an array words
of size n
consisting of non-empty strings.
We define the score of a string word
as the number of strings words[i]
such that word
is a prefix of words[i]
.
- For example, if
words = ["a", "ab", "abc", "cab"]
, then the score of"ab"
is2
, since"ab"
is a prefix of both"ab"
and"abc"
.
Return an array answer
of size n
where answer[i]
is the sum of scores of every non-empty prefix of words[i]
.
Note that a string is considered as a prefix of itself.
Example 1:
Input: words = ["abc","ab","bc","b"] Output: [5,4,3,2] Explanation: The answer for each string is the following: - "abc" has 3 prefixes: "a", "ab", and "abc". - There are 2 strings with the prefix "a", 2 strings with the prefix "ab", and 1 string with the prefix "abc". The total is answer[0] = 2 + 2 + 1 = 5. - "ab" has 2 prefixes: "a" and "ab". - There are 2 strings with the prefix "a", and 2 strings with the prefix "ab". The total is answer[1] = 2 + 2 = 4. - "bc" has 2 prefixes: "b" and "bc". - There are 2 strings with the prefix "b", and 1 string with the prefix "bc". The total is answer[2] = 2 + 1 = 3. - "b" has 1 prefix: "b". - There are 2 strings with the prefix "b". The total is answer[3] = 2.
Example 2:
Input: words = ["abcd"] Output: [4] Explanation: "abcd" has 4 prefixes: "a", "ab", "abc", and "abcd". Each prefix has a score of one, so the total is answer[0] = 1 + 1 + 1 + 1 = 4.
Constraints:
1 <= words.length <= 1000
1 <= words[i].length <= 1000
words[i]
consists of lowercase English letters.
Solution
sum-of-prefix-scores-of-strings.py
# ----------------------------------- Trie -----------------------------------
class Trie:
# https://github.com/cheran-senthil/PyRival/blob/master/pyrival/data_structures/Trie.py
def __init__(self, words):
self.root = dict()
for word in words:
self.add(word)
def add(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, dict())
current_dict["count"] = current_dict.get("count", 0) + 1
current_dict["_end_"] = True
def __contains__(self, word):
current_dict = self.root
for letter in word:
if letter not in current_dict:
return False
current_dict = current_dict[letter]
return "_end_" in current_dict
def delete(self, word, prune=False):
current_dict = self.root
nodes = [current_dict]
objects = []
for letter in word:
current_dict = current_dict[letter]
nodes.append(current_dict)
objects.append(current_dict)
del current_dict["_end_"]
if prune:
# https://leetcode.com/problems/maximum-genetic-difference-query/discuss/1344900/
for c, obj in zip(word[::-1], objects[:-1][::-1]):
if not obj[c]:
del obj[c]
else:
break
# assert word not in self # confirm that the number has been removed
def query(self, word):
current_dict = self.root
total = 0
for letter in word:
if letter not in current_dict: break
current_dict = current_dict[letter]
total += current_dict["count"]
return total
class Solution:
def sumPrefixScores(self, words: List[str]) -> List[int]:
N = len(words)
res = [0] * N
trie = Trie(words)
for index, word in enumerate(words):
res[index] = trie.query(word)
return res