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^4s only consists of a, b or c characters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to this problem is very straightforward. We will look at every possible substring of the given string and then, for each one, check if it meets our criteria of containing all three characters.
Here's how the algorithm would work step-by-step:
def number_of_substrings(input_string):
string_length = len(input_string)
substring_count = 0
for substring_length in range(1, string_length + 1):
for starting_index in range(string_length - substring_length + 1):
substring = input_string[starting_index:starting_index + substring_length]
# Check if the substring contains all three characters.
if ('a' in substring) and ('b' in substring) and ('c' in substring):
substring_count += 1
# Return the total count of substrings that meet the criteria.
return substring_countThe trick is to efficiently find the *earliest* point where we have all three characters. Then, we can count all valid substrings that *start* before or at this point, without checking every single one. We can slide the window to the right repeatedly to count all substring occurrences efficiently.
Here's how the algorithm would work step-by-step:
def number_of_substrings(input_string):
string_length = len(input_string)
count = 0
left = 0
character_counts = {'a': 0, 'b': 0, 'c': 0}
for right in range(string_length):
character_counts[input_string[right]] += 1
# Move left until substring is not valid
while (
character_counts['a'] > 0
and character_counts['b'] > 0
and character_counts['c'] > 0
):
# Count valid substrings ending at right
count += string_length - right
# Shrink the window from the left
character_counts[input_string[left]] -= 1
left += 1
return count| Case | How to Handle |
|---|---|
| Empty string input | Return 0 since an empty string cannot contain all three characters. |
| String with length less than 3 | Return 0 as a string of length less than 3 cannot contain all three distinct characters. |
| String containing only one or two of the required characters (a, b, c) | Return 0, because the substring can never contain all three distinct characters. |
| String with a very long length (e.g., exceeding memory limits) and high repetitions | Ensure the sliding window approach uses constant space and iterates efficiently avoiding memory issues even with large input sizes, and confirm the integer count doesn't overflow. |
| String with all 'a's, 'b's, and 'c's clustered together at the beginning | The sliding window should correctly identify the first valid substring and proceed to count the rest efficiently. |
| String where the last occurrence of one of the characters is near the end | The sliding window should extend correctly to include the last occurrence and terminate appropriately. |
| String with characters other than 'a', 'b', or 'c' | Ignore the other characters and only consider 'a', 'b', and 'c' for the count using conditional checks within the loop. |
| Integer overflow when calculating the number of valid substrings | Use a 64-bit integer type (long) to store the number of substrings to avoid potential overflow issues with very large inputs. |