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.
Solutions
Solution 1: Single Pass
We use an array \(d\) of length \(3\) to record the most recent occurrence of the three characters, initially all set to \(-1\).
We traverse the string \(s\). For the current position \(i\), we first update \(d[s[i]]=i\), then the number of valid strings is \(\min(d[0], d[1], d[2]) + 1\), which is accumulated to the answer.
The time complexity is \(O(n)\), where \(n\) is the length of the string \(s\). The space complexity is \(O(1)\).
We can solve this using a sliding window. Maintain a window \([l, r]\) and an array \(\textit{cnt}\) recording the frequency of each character in the window.
Traverse the string and keep moving the right boundary \(r\) to include \(s[r]\). If the window contains at least one \(a\), \(b\), and \(c\), keep moving the left boundary \(l\) to the right until the window no longer contains all three characters.
At this point, all substrings ending at \(r\) that contain \(a\), \(b\), and \(c\) can start at indices \(0, 1, \ldots, l - 1\), giving \(l\) valid substrings in total. Add this count to the answer.
The time complexity is \(O(n)\), where \(n\) is the length of the string \(s\). The space complexity is \(O(1)\).