I have a binary string of 0's and 1's. Now I want to select a string of length 3 such that no consecutive characters are same.
Example:
Input : 01011010
Output: 20
Explanation: All possible combinations are:
[0, 1, 0]:: indices : 0,1,2 :: valid
[0, 1, 1]:: indices : 0,1,3
[0, 1, 1]:: indices : 0,1,4
[0, 1, 0]:: indices : 0,1,5 :: valid
[0, 1, 1]:: indices : 0,1,6
[0, 1, 0]:: indices : 0,1,7 :: valid
[0, 0, 1]:: indices : 0,2,3
[0, 0, 1]:: indices : 0,2,4
[0, 0, 0]:: indices : 0,2,5
[0, 0, 1]:: indices : 0,2,6
[0, 0, 0]:: indices : 0,2,7
[0, 1, 1]:: indices : 0,3,4
[0, 1, 0]:: indices : 0,3,5 :: valid
[0, 1, 1]:: indices : 0,3,6
[0, 1, 0]:: indices : 0,3,7 :: valid
[0, 1, 0]:: indices : 0,4,5 :: valid
[0, 1, 1]:: indices : 0,4,6
[0, 1, 0]:: indices : 0,4,7 :: valid
[0, 0, 1]:: indices : 0,5,6
[0, 0, 0]:: indices : 0,5,7
[0, 1, 0]:: indices : 0,6,7 :: valid
[1, 0, 1]:: indices : 1,2,3 :: valid
[1, 0, 1]:: indices : 1,2,4 :: valid
[1, 0, 0]:: indices : 1,2,5
[1, 0, 1]:: indices : 1,2,6 :: valid
[1, 0, 0]:: indices : 1,2,7
[1, 1, 1]:: indices : 1,3,4
[1, 1, 0]:: indices : 1,3,5
[1, 1, 1]:: indices : 1,3,6
[1, 1, 0]:: indices : 1,3,7
[1, 1, 0]:: indices : 1,4,5
[1, 1, 1]:: indices : 1,4,6
[1, 1, 0]:: indices : 1,4,7
[1, 0, 1]:: indices : 1,5,6 :: valid
[1, 0, 0]:: indices : 1,5,7
[1, 1, 0]:: indices : 1,6,7
[0, 1, 1]:: indices : 2,3,4
[0, 1, 0]:: indices : 2,3,5 :: valid
[0, 1, 1]:: indices : 2,3,6
[0, 1, 0]:: indices : 2,3,7 :: valid
[0, 1, 0]:: indices : 2,4,5 :: valid
[0, 1, 1]:: indices : 2,4,6
[0, 1, 0]:: indices : 2,4,7 :: valid
[0, 0, 1]:: indices : 2,5,6
[0, 0, 0]:: indices : 2,5,7
[0, 1, 0]:: indices : 2,6,7 :: valid
[1, 1, 0]:: indices : 3,4,5
[1, 1, 1]:: indices : 3,4,6
[1, 1, 0]:: indices : 3,4,7
[1, 0, 1]:: indices : 3,5,6 :: valid
[1, 0, 0]:: indices : 3,5,7
[1, 1, 0]:: indices : 3,6,7
[1, 0, 1]:: indices : 4,5,6 :: valid
[1, 0, 0]:: indices : 4,5,7
[1, 1, 0]:: indices : 4,6,7
[0, 1, 0]:: indices : 5,6,7 :: valid
Of these only 20 combinations are valid so output is 20.
Here is my program.
public static long process(String s) {
long result = 0;
int n = s.length();
for (int i = 0; i < n; i ) {
for (int j = i 1; j < n; j ) {
if (s.charAt(i) == s.charAt(j)) {
continue;
}
for (int k = j 1; k < n; k ) {
if (s.charAt(j) != s.charAt(k)) {
result ;
}
}
}
}
return result;
}
Constaints:
length of input is 1 to 2*10^5.
How to reduce time complexity of this program.
CodePudding user response:
Let's first look at all possible binary strings of length 3 such that no consecutive characters are same:
101
010
With that in mind the problem can be reformulated to:
for each 0 in input, find all combinations of 1 on either side, plus
for each 1 in input, find all combinations of 0 on either side
For any given 0
, the number of combinations of 1
on either side is equal to the number of 1
to the left times the number of 1
to the right (and vice-versa).
Finally, we can combine these two for
loops into one by switching between the two cases based on the current character. We should also keep track of the 0
and 1
to the left and right, as we don't want to recalculate them all the time. This leaves me with the following algorithm:
var leftZeroes = 0
var leftOnes = 0
var rightZeroes = input.count { it == '0' }
var rightOnes = input.count { it == '1' }
var output = 0
for (char in input) {
if (char == '0') {
output = leftOnes * rightOnes
leftZeroes
rightZeroes--
} else {
output = leftZeroes * rightZeroes
leftOnes
rightOnes--
}
}
return output
Time complexity: O(n)
(count
and for
are linear in input size, everything else is constant)
Additional space complexity would be O(1)
, as only those five integers are stored at any time