Sum of Scores of Built Strings
HardUpdated: Aug 2, 2025
Practice on:
Problem
You are building a string s of length n one character at a time,
prepending each new character to the front of the string. The strings are labeled from 1 to n, where the string with length i is labeled si.
- For example, for
s = "abaca",s1 == "a",s2 == "ca",s3 == "aca", etc.
The score of si is the length of the longest common prefix between
si and sn (Note that s == sn).
Given the final string s, return _thesum of the score of every _si.
Examples
Example 1
Input: s = "babab"
Output: 9
Explanation:
For s1 == "b", the longest common prefix is "b" which has a score of 1.
For s2 == "ab", there is no common prefix so the score is 0.
For s3 == "bab", the longest common prefix is "bab" which has a score of 3.
For s4 == "abab", there is no common prefix so the score is 0.
For s5 == "babab", the longest common prefix is "babab" which has a score of 5.
The sum of the scores is 1 + 0 + 3 + 0 + 5 = 9, so we return 9.
Example 2
Input: s = "azbazbzaz"
Output: 14
Explanation:
For s2 == "az", the longest common prefix is "az" which has a score of 2.
For s6 == "azbzaz", the longest common prefix is "azb" which has a score of 3.
For s9 == "azbazbzaz", the longest common prefix is "azbazbzaz" which has a score of 9.
For all other si, the score is 0.
The sum of the scores is 2 + 3 + 9 = 14, so we return 14.
Constraints
1 <= s.length <= 10^5sconsists of lowercase English letters.
Solution
Approach
For each si, the score is the length of the longest common prefix between si and s. This is equivalent to computing the Z-array (Z-algorithm) for the string s. The sum of all Z-values plus n (for the full string) gives the answer.
Code
C++
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
long long sumScores(string s) {
int n = s.size();
vector<int> z(n);
long long res = n;
for (int i = 1, l = 0, r = 0; i < n; ++i) {
if (i <= r) z[i] = min(r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
res += z[i];
}
return res;
}
};
Java
class Solution {
public long sumScores(String s) {
int n = s.length();
int[] z = new int[n];
long res = n;
for (int i = 1, l = 0, r = 0; i < n; ++i) {
if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]);
while (i + z[i] < n && s.charAt(z[i]) == s.charAt(i + z[i])) ++z[i];
if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1; }
res += z[i];
}
return res;
}
}
Kotlin
class Solution {
fun sumScores(s: String): Long {
val n = s.length
val z = IntArray(n)
var res = n.toLong()
var l = 0; var r = 0
for (i in 1 until n) {
if (i <= r) z[i] = minOf(r - i + 1, z[i - l])
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]
if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1 }
res += z[i]
}
return res
}
}
Python
class Solution:
def sumScores(self, s: str) -> int:
n = len(s)
z = [0] * n
res = n
l = r = 0
for i in range(1, n):
if i <= r:
z[i] = min(r - i + 1, z[i - l])
while i + z[i] < n and s[z[i]] == s[i + z[i]]:
z[i] += 1
if i + z[i] - 1 > r:
l, r = i, i + z[i] - 1
res += z[i]
return res
Rust
impl Solution {
pub fn sum_scores(s: String) -> i64 {
let n = s.len();
let s = s.as_bytes();
let mut z = vec![0; n];
let mut res = n as i64;
let (mut l, mut r) = (0, 0);
for i in 1..n {
if i <= r { z[i] = z[i-l].min(r-i+1); }
while i + z[i] < n && s[z[i]] == s[i+z[i]] { z[i] += 1; }
if i + z[i] - 1 > r { l = i; r = i + z[i] - 1; }
res += z[i] as i64;
}
res
}
}
TypeScript
function sumScores(s: string): number {
const n = s.length;
const z = new Array(n).fill(0);
let res = n;
let l = 0, r = 0;
for (let i = 1; i < n; ++i) {
if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] === s[i + z[i]]) ++z[i];
if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1; }
res += z[i];
}
return res;
}
Complexity
- ⏰ Time complexity:
O(n) - 🧺 Space complexity:
O(n)