Sum of Prefix Scores of Strings
HARDDescription
You are given an array words of size n consisting of non-empty strings.
We define the score of a string term as the number of strings words[i] such that term 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 <= 10001 <= words[i].length <= 1000words[i]consists of lowercase English letters.
Approaches
Checkout 3 different approaches to solve Sum of Prefix Scores of Strings. Click on different approaches to view the approach and algorithm in detail.
Optimal Approach using a Trie (Prefix Tree)
The most efficient solution utilizes a Trie data structure, which is perfectly suited for problems involving prefixes. We first build a Trie from all the words, incrementing a counter in each node to track how many words pass through it (i.e., the prefix score). Then, for each word, we traverse the Trie and sum the counters of the nodes corresponding to its prefixes.
Algorithm
- Define a
TrieNodeclass containing an array of children (e.g., size 26 for lowercase English letters) and an integercount. - First Pass (Build Trie):
- Create a
rootnode for the Trie. - Iterate through each
wordin thewordsarray. - For each
word, traverse the Trie from theroot, character by character. - For each character, move to the corresponding child node. If it doesn't exist, create it.
- Increment the
countof the visited node. Thiscountrepresents the score of the prefix ending at that node.
- Create a
- Second Pass (Calculate Scores):
- Initialize an integer array
answerof sizen. - Iterate through each
wordat indexiin thewordsarray. - Initialize
totalScoreto 0. - Traverse the Trie again for the current
word, character by character. - At each node in the traversal, add its
counttototalScore. - After traversing the entire word, store
totalScoreinanswer[i].
- Initialize an integer array
- Return the
answerarray.
A Trie, or prefix tree, is an ideal data structure for this problem. Each node in the Trie can represent a character, and a path from the root to a node represents a prefix. We can augment the Trie node to store a count of how many words in the input array share the prefix represented by that node.
The algorithm works in two passes:
- Build Trie and Count Prefixes: We insert every word from the input array into the Trie. While inserting a word, we traverse the Trie character by character. For each node we visit (or create), we increment its
countfield. By the end of this pass, thecountat any node will represent the score of the prefix corresponding to that node. - Calculate Sum of Scores: We iterate through the input
wordsarray again. For each word, we traverse the Trie following the path of its characters. As we visit each node along the path, we add itscountto a running total for the current word. This sum is the answer for that word.
This approach is highly efficient because it processes each character of each word a constant number of times.
class TrieNode {
TrieNode[] children;
int count;
public TrieNode() {
children = new TrieNode[26];
count = 0;
}
}
class Solution {
public int[] sumPrefixScores(String[] words) {
TrieNode root = new TrieNode();
// Pass 1: Build the Trie and count prefixes
for (String word : words) {
TrieNode curr = root;
for (char c : word.toCharArray()) {
int index = c - 'a';
if (curr.children[index] == null) {
curr.children[index] = new TrieNode();
}
curr = curr.children[index];
curr.count++;
}
}
int n = words.length;
int[] answer = new int[n];
// Pass 2: Calculate the sum of scores for each word
for (int i = 0; i < n; i++) {
String word = words[i];
TrieNode curr = root;
int totalScore = 0;
for (char c : word.toCharArray()) {
int index = c - 'a';
curr = curr.children[index];
totalScore += curr.count;
}
answer[i] = totalScore;
}
return answer;
}
}
Complexity Analysis
Pros and Cons
- Highly efficient in both time and space.
- It's the optimal solution for this problem as it avoids string manipulations and redundant computations.
- Requires knowledge of the Trie data structure, making it slightly more complex to implement than the other approaches.
Code Solutions
Checking out 4 solutions in different languages for Sum of Prefix Scores of Strings. Click on different languages to view the code.
class Trie { private Trie [] children = new Trie [ 26 ]; private int cnt ; public void insert ( String w ) { Trie node = this ; for ( char c : w . toCharArray ()) { c -= 'a' ; if ( node . children [ c ] == null ) { node . children [ c ] = new Trie (); } node = node . children [ c ]; ++ node . cnt ; } } public int search ( String w ) { Trie node = this ; int ans = 0 ; for ( char c : w . toCharArray ()) { c -= 'a' ; if ( node . children [ c ] == null ) { return ans ; } node = node . children [ c ]; ans += node . cnt ; } return ans ; } } class Solution { public int [] sumPrefixScores ( String [] words ) { Trie trie = new Trie (); for ( String w : words ) { trie . insert ( w ); } int [] ans = new int [ words . length ]; for ( int i = 0 ; i < words . length ; ++ i ) { ans [ i ] = trie . search ( words [ i ]); } return ans ; } }Video Solution
Watch the video walkthrough for Sum of Prefix Scores of Strings
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.