1358. Number of Substrings Containing All Three Characters
Difficulty: Medium | Date: 2026-06-30
Patterns: Sliding Window Data Structures: String
Problem
Given a string s consisting only of 'a', 'b', and 'c', return the number of substrings containing at least one occurrence of all three characters.
My Approach
I recognized it as sliding window but got stuck on two things: when to shrink, and how to count. My instinct was to expand until valid and count then, but I couldn’t figure out the math.
The counterintuitive move: shrink while the window IS valid (not when it’s invalid like most sliding window problems). Keep shrinking left until the window breaks. At that point, left tells you how many valid starting positions exist for the current right endpoint.
Key Insight
The result += left counting formula for “at least” substring problems.
After shrinking left until the window just becomes invalid:
- The window
[left, right]is the first invalid window - So
[left-1, right],[left-2, right], …,[0, right]are all valid - That’s exactly
leftvalid substrings ending atright - Add
leftto result for every right
This works because once a window ending at right is valid, making it longer (moving start left) keeps it valid. So you only need to find the boundary.
Solution
def numberOfSubstrings(s: str) -> int:
count = {'a': 0, 'b': 0, 'c': 0}
left = 0
result = 0
for right in range(len(s)):
count[s[right]] += 1
# shrink while valid — opposite of typical sliding window
while count['a'] > 0 and count['b'] > 0 and count['c'] > 0:
count[s[left]] -= 1
left += 1
# left = number of valid starting positions for this right
result += left
return resultComplexity
- Time: O(n) - each character is added and removed from the window at most once
- Space: O(1) - fixed-size count dict (only 3 keys)
The Reusable Formula
For “count substrings with at least X” problems:
- Shrink while valid, stop when invalid
result += leftat each step
Contrast with “count substrings with exactly X” = atLeast(X) - atLeast(X+1)