Given a string s
consisting only of characters a, b and c.
Return the number of substrings containing at least one occurrence of all these characters a, b and c.
Example 1:
Input: s = "abcabc"
Output: 10
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc" and "abc" (again).
Example 2:
Input: s = "aaacb"
Output: 3
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "aaacb", "aacb" and "acb".
Example 3:
Input: s = "abc"
Output: 1
Constraints:
3 <= s.length <= 5 x 10^4
s
only consists of a, b or c characters.def number_of_substrings(s: str) -> int:
"""Given a string s consisting only of characters a, b and c.
Return the number of substrings containing at least one occurrence of all these characters a, b and c.
"""
n = len(s)
count = 0
for i in range(n):
for j in range(i, n):
sub = s[i:j+1]
if 'a' in sub and 'b' in sub and 'c' in sub:
count += 1
return count
# Example usage
s = "abcabc"
print(number_of_substrings(s))
s = "aaacb"
print(number_of_substrings(s))
s = "abc"
print(number_of_substrings(s))
# Optimal solution using sliding window
def number_of_substrings_optimal(s: str) -> int:
n = len(s)
count = 0
left = 0
freq = {'a': 0, 'b': 0, 'c': 0}
for right in range(n):
freq[s[right]] += 1
while freq['a'] > 0 and freq['b'] > 0 and freq['c'] > 0:
count += n - right
freq[s[left]] -= 1
left += 1
return count
# Example usage
s = "abcabc"
print(number_of_substrings_optimal(s))
s = "aaacb"
print(number_of_substrings_optimal(s))
s = "abc"
print(number_of_substrings_optimal(s))
The brute force solution iterates through all possible substrings of the input string s
and checks if each substring contains at least one occurrence of characters 'a', 'b', and 'c'. If a substring satisfies this condition, the count is incremented. The final count represents the number of substrings that meet the criteria.
The optimal solution uses a sliding window approach to efficiently count the substrings. It maintains a window defined by left
and right
pointers. The window expands to the right, and the frequency of characters within the window is tracked using a dictionary freq
. Once the window contains at least one occurrence of each character ('a', 'b', and 'c'), the algorithm increments the count by the number of substrings that can be formed by extending the window to the end of the string (n - right). Then, the window shrinks from the left until one of the characters is no longer present in the window, ensuring that the window always contains the minimum required characters. This process continues until the right pointer reaches the end of the string.
in
operator within the inner loop takes O(n) time in the worst case.right
pointer iterates through the string once, and the left
pointer also iterates through the string at most once. The operations inside the loops take constant time.freq
dictionary always contains at most three key-value pairs ('a', 'b', and 'c').