Minimum Number of Flips to Make the Binary String Alternating
You are given a binary string s
- Type 1: move the first character to the end of the string.
- Type 2: flip any one character, 0 to 1 or 1 to 0.
Return the minimum number of type-2 operations needed to make s
Example 1
Output: 2
Explanation: rotate twice to get "100011", then flip the third and sixth characters to get "101010".
Example 2
Output: 0
Explanation: already alternating.
Example 3
Output: 1
Explanation: flip the second character to get "1010".
How to Think About It
Step 1: Without rotation
There are only two alternating strings of length n: one starting with 0 ("0101...") and one starting with 1 ("1010..."). The flips needed are the mismatches with whichever of the two is closer.
Every character matches exactly one of the two patterns, so if diffAn - diffA
Step 2: Rotations are windows of s + s
Type-1 operations are free, so we can try every rotation. Writing the string twice, t = s + sst
For "111000", t
Step 3: Slide the window and update the mismatch counts
Compare t
- When character
enters, add it toi ordiffA .diffB - When character
leaves, subtract it the same way.i - n - For every full window, the answer candidate is
.min(diffA, diffB)
Walkthrough
s = "1110"t = "11101110"
| Window (a rotation of s) | Mismatches with the pattern starting 0 | Mismatches with the pattern starting 1 | Flips |
|---|---|---|---|
| 1110 | 3 | 1 | 1 |
| 1101 | 1 | 3 | 1 |
| 1011 | 3 | 1 | 1 |
| 0111 | 1 | 3 | 1 |
The patterns are lined up with positions in t
Java Solution
The doubled string is built once; a character that is a mismatch for one pattern is a match for the other, so one comparison updates both counts.
public class MinimumNumberOfFlipsToMakeTheBinaryStringAlternate {
public static int minFlips(String s) {
int n = s.length();
String t = s + s; // every rotation is a window of length n in t
int diffA = 0; // mismatches with "0101..." in the window
int diffB = 0; // mismatches with "1010..." in the window
int best = Integer.MAX_VALUE;
for (int i = 0; i < 2 * n; i++) {
char expectA = (i % 2 == 0) ? '0' : '1';
if (t.charAt(i) != expectA) {
diffA++;
} else {
diffB++; // a match with one pattern is a miss for the other
}
if (i >= n) { // character i - n leaves the window
char outExpectA = ((i - n) % 2 == 0) ? '0' : '1';
if (t.charAt(i - n) != outExpectA) {
diffA--;
} else {
diffB--;
}
}
if (i >= n - 1) {
best = Math.min(best, Math.min(diffA, diffB));
}
}
return best;
}
public static void main(String[] args) {
System.out.println(minFlips("111000")); // 2
System.out.println(minFlips("010")); // 0
System.out.println(minFlips("1110")); // 1
}
}
The original implementation,
Complexity
- Time: O(n): one pass over a string of length 2n.
- Space: O(n) for the doubled string. Indexing
withs avoids even that.i % n
Doubling a string to see all its rotations also solves