The appeal of a string is the number of distinct characters found in the string.
"abbca"
is 3
because it has 3
distinct 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 <= 105
s
consists of lowercase English letters.This problem asks to calculate the total appeal of all substrings of a given string. The appeal of a string is defined as the number of distinct characters in it. The solution uses a linear time approach leveraging the observation that we don't need to explicitly generate all substrings.
Approach:
The core idea is to iteratively process the string and maintain information about the last seen position of each character. For each character, we calculate its contribution to the total appeal by considering its impact on the appeal of all substrings ending at that character.
Let's illustrate with an example: s = "abbca"
Initialization: We use an array pos
of size 26 (for lowercase English letters) to store the last seen index of each character. Initially, all entries are -1.
Iteration: The algorithm iterates through the string:
c
at index i
:
c
to the total appeal. This contribution is determined by the number of substrings ending at index i
whose appeal increases because of c
.i - pos[c]
. If pos[c]
is -1 (first occurrence), it's i + 1
.ans
) by adding the contribution.pos[c]
to the current index i
.Time Complexity Analysis:
The algorithm iterates through the string once. The operations within the loop (array access, addition) are constant time. Therefore, the overall time complexity is O(n), where n is the length of the string.
Space Complexity Analysis:
The algorithm uses a fixed-size array pos
to store the last seen indices of each character. The size of this array is constant (26). Therefore, the space complexity is O(1), which is constant.
Code Explanation (Python):
class Solution:
def appealSum(self, s: str) -> int:
ans = t = 0 # ans: total appeal, t: appeal contribution for substrings ending at current index
pos = [-1] * 26 # pos[c]: last seen index of character c
for i, c in enumerate(s):
c_index = ord(c) - ord('a') #Convert character to its index (0-25)
t += i - pos[c_index] # Calculate contribution: substrings ending at i with increased appeal due to c
ans += t # Add contribution to total appeal
pos[c_index] = i # Update last seen index of c
return ans
The other languages (Java, C++, Go, TypeScript) follow the same logic, only differing in syntax. The core idea of using a pos
array to track last seen indices and iteratively calculating the contribution to the total appeal remains consistent across all implementations.