forked from realpacific/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlipBitToWin.java
90 lines (81 loc) · 3.14 KB
/
FlipBitToWin.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;
}
}