You are given a 0-indexed binary string s
which represents the types of buildings along a street where:
s[i] = '0'
denotes that the ith
building is an office ands[i] = '1'
denotes that the ith
building is a restaurant.As a city official, you would like to select 3 buildings for random inspection. However, to ensure variety, no two consecutive buildings out of the selected buildings can be of the same type.
s = "001101"
, we cannot select the 1st
, 3rd
, and 5th
buildings as that would form "011"
which is not allowed due to having two consecutive buildings of the same type.Return the number of valid ways to select 3 buildings.
Example 1:
Input: s = "001101" Output: 6 Explanation: The following sets of indices selected are valid: - [0,2,4] from "001101" forms "010" - [0,3,4] from "001101" forms "010" - [1,2,4] from "001101" forms "010" - [1,3,4] from "001101" forms "010" - [2,4,5] from "001101" forms "101" - [3,4,5] from "001101" forms "101" No other selection is valid. Thus, there are 6 total ways.
Example 2:
Input: s = "11100" Output: 0 Explanation: It can be shown that there are no valid selections.
Constraints:
3 <= s.length <= 105
s[i]
is either '0'
or '1'
.This problem asks us to find the number of ways to select three buildings from a street such that no two consecutive buildings are of the same type. The buildings are represented by a binary string, where '0' denotes an office and '1' denotes a restaurant.
Approach:
The most efficient approach uses a linear scan with prefix sums. Instead of brute-force enumeration of all possible triplets, we utilize the following observation:
The algorithm works as follows:
Initialization: We create two arrays, l
and r
. l[i]
keeps track of the count of buildings of type i
to the left of the currently considered building, and r[i]
keeps track of the count of buildings of type i
to the right. Initially, r
is populated with the total counts of '0's and '1's in the string.
Iteration: We iterate through the input string s
. For each building at index i
:
r
.l[x ^ 1] * r[x ^ 1]
, where x
is the type of the current building (0 or 1), and x ^ 1
represents the opposite type. The product represents all possible combinations of left and right buildings that satisfy the condition.l
.Return: After iterating through all buildings, the accumulated ans
will be the total number of valid selections.
Time Complexity: O(n), where n is the length of the string. We iterate through the string once.
Space Complexity: O(1). We use a constant amount of extra space for the l
and r
arrays.
Code (Python):
class Solution:
def numberOfWays(self, s: str) -> int:
l = [0, 0] # Count of 0s and 1s to the left
r = [s.count('0'), s.count('1')] # Count of 0s and 1s to the right
ans = 0
for x in map(int, s): # Iterate through the string (converting chars to ints)
r[x] -= 1
ans += l[x ^ 1] * r[x ^ 1]
l[x] += 1
return ans
Code (Java):
class Solution {
public long numberOfWays(String s) {
int[] l = new int[2];
int[] r = new int[2];
for (char c : s.toCharArray()) {
r[c - '0']++;
}
long ans = 0;
for (char c : s.toCharArray()) {
int x = c - '0';
r[x]--;
ans += (long)l[x ^ 1] * r[x ^ 1];
l[x]++;
}
return ans;
}
}
The other languages (C++, Go, TypeScript) follow a very similar structure, adapting the syntax to the respective language. The core logic remains the same efficient linear scan using prefix-sum-like counting.