Skip to main content

Flip Bit To Win

Find the largest sequence of 1 that can be obtained by flipping a 0 to 1.

package bits;

import java.util.Stack;

/**
* Find the largest sequence of 1 that can be obtained by flipping a 0 to 1.
*/
public class FlipBitToWin {
public static void main(String[] args) {
assert flipToWin("1101111100111") == 8;

assert flipToWin("11011101111") == 8;
assert flipToWin("110011100111101") == 6;
assert flipToWin("11111111111101") == 14;
assert flipToWin("010000000") == 1;
assert flipToWin("0000000") == 1;
assert flipToWin("00000000010000001000001101") == 4;
assert flipToWin("000001110000011") == 3;
assert flipToWin("010101110100011") == 5;
assert flipToWin("000001110001011") == 4;
assert flipToWin("000000000") == 1;
assert flipToWin("1111") == 4;
assert flipToWin("1111001111111") == 7;
}

private static int flipToWin(String bit) {
Stack<Integer> stack = new Stack<>();
int countOfOnes = 0;
int countOfZeros = 0;

// Count the number of 1s and push the count in stack
for (int i = 0; i < bit.length(); i++) {
if (bit.charAt(i) == '1') {
countOfZeros = 0;
countOfOnes++;
} else {
countOfZeros++;
// if 2 or more 0s occur sequentially, push -1 if latest element is not -1
// This will make sure 2 or more continuous 0s is denoted by -1 in the stack.
if (countOfZeros > 1) {
if (stack.isEmpty() || stack.peek() != -1) {
stack.push(-1);
}
} else {
if (countOfOnes > 0) stack.push(countOfOnes);
}
countOfOnes = 0;
}
}

// Push one last time as for loop exits before putting it on the stack
if (countOfOnes > 0) {
stack.push(countOfOnes);
}

// If stack comprises of [-1], [1]
if (stack.size() == 1) {
// 0000 ---> 1
// 1111 ---> 4
return Math.max(1, stack.peek());
}
System.out.println(stack);

return findLongestPossibleSequence(stack);
}

private static int findLongestPossibleSequence(Stack<Integer> stack) {
int longestPossibleSequence = 0;
// Using rolling window
for (int i = 1; i < stack.size(); i++) {
int prev = stack.get(i - 1);
int now = stack.get(i);
int sum = 0;
// if one of them is -1, then sum is the max of two
// [(5, -1), 1, 4]
// -1 denotes continuous occurrence of 0s
if (prev == -1 || now == -1) {
sum = Math.max(prev, now);
} else {
// if none of them is -1, then sum them and add 1 as only one 0s exists between them
// which can be flipped
sum = prev + now + 1;
}
// override [longestPossibleSequence] if it is less than sum
longestPossibleSequence = Math.max(longestPossibleSequence, sum);
}
System.out.println(longestPossibleSequence);
return longestPossibleSequence;
}
}


Updated on 2021-02-03