Total Appeal of A String
HARDDescription
The appeal of a string is the number of distinct characters found in the string.
- For example, the appeal of
"abbca"is3because it has3distinct characters:'a','b', and'c'.
Given a string s, return the total appeal of all of its substrings.
A substring is a contiguous sequence of characters within a string.
Example 1:
Input: s = "abbca" Output: 28 Explanation: The following are the substrings of "abbca": - Substrings of length 1: "a", "b", "b", "c", "a" have an appeal of 1, 1, 1, 1, and 1 respectively. The sum is 5. - Substrings of length 2: "ab", "bb", "bc", "ca" have an appeal of 2, 1, 2, and 2 respectively. The sum is 7. - Substrings of length 3: "abb", "bbc", "bca" have an appeal of 2, 2, and 3 respectively. The sum is 7. - Substrings of length 4: "abbc", "bbca" have an appeal of 3 and 3 respectively. The sum is 6. - Substrings of length 5: "abbca" has an appeal of 3. The sum is 3. The total sum is 5 + 7 + 7 + 6 + 3 = 28.
Example 2:
Input: s = "code" Output: 20 Explanation: The following are the substrings of "code": - Substrings of length 1: "c", "o", "d", "e" have an appeal of 1, 1, 1, and 1 respectively. The sum is 4. - Substrings of length 2: "co", "od", "de" have an appeal of 2, 2, and 2 respectively. The sum is 6. - Substrings of length 3: "cod", "ode" have an appeal of 3 and 3 respectively. The sum is 6. - Substrings of length 4: "code" has an appeal of 4. The sum is 4. The total sum is 4 + 6 + 6 + 4 = 20.
Constraints:
1 <= s.length <= 105sconsists of lowercase English letters.
Approaches
Checkout 3 different approaches to solve Total Appeal of A String. Click on different approaches to view the approach and algorithm in detail.
Linear Time Solution using Contribution of Characters
Instead of iterating through substrings, we can change our perspective and calculate the total contribution of each character to the final sum. The total appeal is the sum of appeals of all substrings. This can be rephrased as summing, for each character c in the alphabet, the number of substrings that contain c. A more direct way is to consider the contribution of each character s[i] to the total appeal.
Algorithm
- Initialize
totalAppealto 0. - Create an array
lastSeenof size 26 and initialize all its elements to -1. This array will store the last index at which each character was seen. - Iterate through the string
sfromi = 0ton-1. - For the character
c = s.charAt(i), find its previous indexprev_idxfromlastSeen[c - 'a']. - Calculate the contribution of
s[i]as(i - prev_idx) * (n - i). - Add this contribution to
totalAppeal. - Update the last seen index for
c:lastSeen[c - 'a'] = i. - After the loop, return
totalAppeal.
The core idea is that a character s[i] adds +1 to the appeal of a substring if it's the first occurrence of that character within that substring. For a character s[i], we need to count how many substrings s[start..end] contain s[i] as their first instance of that character.
Let prev_idx be the index of the previous occurrence of the character s[i] (or -1 if it's the first time). For s[i] to be the first occurrence in s[start..end], we must have start > prev_idx. Also, the substring must contain s[i], so start <= i <= end.
Combining these conditions:
- The
startindex can be any value fromprev_idx + 1toi. This givesi - (prev_idx + 1) + 1 = i - prev_idxchoices. - The
endindex can be any value fromiton-1. This gives(n-1) - i + 1 = n - ichoices.
Thus, s[i] contributes (i - prev_idx) * (n - i) to the total appeal. We can iterate through the string once, calculating and summing these contributions.
import java.util.Arrays;
class Solution {
public long appealSum(String s) {
long totalAppeal = 0;
int n = s.length();
// lastSeen[char_code] stores the last index where the character appeared.
int[] lastSeen = new int[26];
Arrays.fill(lastSeen, -1);
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
int charIndex = c - 'a';
int prevIndex = lastSeen[charIndex];
// Number of substrings where s[i] is the first occurrence of this character.
// A substring s[start..end] must satisfy:
// prevIndex < start <= i
// i <= end < n
// Number of choices for start: i - prevIndex
// Number of choices for end: n - i
long contribution = (long)(i - prevIndex) * (n - i);
totalAppeal += contribution;
// Update the last seen index for the current character.
lastSeen[charIndex] = i;
}
return totalAppeal;
}
}
Complexity Analysis
Pros and Cons
- Highly efficient, optimal solution that passes all test cases within the time limit.
- The logic is less intuitive than brute-force approaches and requires a shift in perspective to counting contributions.
Code Solutions
Checking out 3 solutions in different languages for Total Appeal of A String. Click on different languages to view the code.
class Solution {
public
long appealSum(String s) {
long ans = 0;
long t = 0;
int[] pos = new int[26];
Arrays.fill(pos, -1);
for (int i = 0; i < s.length(); ++i) {
int c = s.charAt(i) - 'a';
t += i - pos[c];
ans += t;
pos[c] = i;
}
return ans;
}
}
Video Solution
Watch the video walkthrough for Total Appeal of A String
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.