Given a binary string s
, return the number of non-empty substrings that have the same number of 0
's and 1
's, and all the 0
's and all the 1
's in these substrings are grouped consecutively.
Substrings that occur multiple times are counted the number of times they occur.
Example 1:
Input: s = "00110011" Output: 6 Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01". Notice that some of these substrings repeat and are counted the number of times they occur. Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
Example 2:
Input: s = "10101" Output: 4 Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
Constraints:
1 <= s.length <= 105
s[i]
is either '0'
or '1'
.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:
To solve this problem the brute force way, we look at every possible chunk of the input string. We will check each chunk to see if it satisfies a certain requirement, incrementing a counter if it does. Finally, the counter will represent the number of valid substrings.
Here's how the algorithm would work step-by-step:
def count_binary_substrings_brute_force(input_string):
number_of_binary_substrings = 0
string_length = len(input_string)
for substring_length in range(2, 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 is valid and increment if so
if is_valid_binary_substring(substring):
number_of_binary_substrings += 1
return number_of_binary_substrings
def is_valid_binary_substring(substring):
group_size = 0
# Determine the expected length of the groups for equality check
if len(substring) % 2 != 0:
return False
group_size = len(substring) // 2
first_char = substring[0]
first_group = ''
second_group = ''
# Split the substring into two groups
for index in range(len(substring)):
if index < group_size:
first_group += substring[index]
else:
second_group += substring[index]
# Ensure both groups are not empty
if not first_group or not second_group:
return False
#Ensure both groups are of same character type
if not all(bit == first_group[0] for bit in first_group):
return False
if not all(bit == second_group[0] for bit in second_group):
return False
# Check if the groups are composed of alternating bits
if first_group[0] == second_group[0]:
return False
return True
The optimal strategy focuses on identifying consecutive groups of similar digits. Instead of checking every possible substring, it leverages the pattern that valid substrings must have an equal count of adjacent 0s and 1s, and these groups must be adjacent to each other.
Here's how the algorithm would work step-by-step:
def countBinarySubstrings(binary_string):
group_lengths = []
current_index = 0
while current_index < len(binary_string):
current_character = binary_string[current_index]
current_length = 0
# Count consecutive characters
while current_index < len(binary_string) and binary_string[current_index] == current_character:
current_length += 1
current_index += 1
group_lengths.append(current_length)
number_of_substrings = 0
# Iterate through adjacent group lengths
for index in range(1, len(group_lengths)):
#Find the minimum length of adjacent groups
number_of_substrings += min(group_lengths[index - 1], group_lengths[index])
return number_of_substrings
Case | How to Handle |
---|---|
Empty or null input string | Return 0, as there are no substrings to evaluate. |
String with a single character | Return 0, as a single character cannot form a valid substring. |
String with only one type of character (e.g., '0000' or '1111') | Return 0, because no valid substring composed of consecutive groups of 0's and 1's can be formed. |
String alternates characters rapidly (e.g., '01010101') | This maximizes the number of valid substrings, and the algorithm should correctly count them. |
String with a very long sequence of the same character followed by a very long sequence of the other character (e.g., '00000000001111111111') | The number of valid substrings is limited by the shorter sequence length, and the algorithm should correctly calculate this. |
Maximum input string length (scalability) | The solution should have a linear time complexity (O(n)) to handle large input strings efficiently. |
Input string contains characters other than '0' or '1' | The solution should either throw an error or gracefully handle the unexpected characters, perhaps by ignoring them or replacing them with a default value and proceeding. |
Integer overflow when calculating the number of substrings in a very long alternating string. | Ensure that the data type used to store the count of substrings is large enough (e.g., long) to prevent integer overflow. |