Created
February 27, 2026 19:30
-
-
Save tatsuyax25/e284f0ed9af657caebb74eb0b7f4bba5 to your computer and use it in GitHub Desktop.
You are given a binary string s, and an integer k. In one operation, you must choose exactly k different indices and flip each '0' to '1' and each '1' to '0'. Return the minimum number of operations required to make all characters in the string equ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @param {string} s | |
| * @param {number} k | |
| * @return {number} | |
| * | |
| * This solution is based on analyzing how many zeros can be flipped per operation. | |
| * Each operation flips exactly k bits, so the parity of the zero count changes | |
| * depending on k. The editorial shows that the minimum number of operations can be | |
| * computed using two candidate formulas depending on parity constraints. | |
| */ | |
| var minOperations = function (s, k) { | |
| const n = s.length; | |
| // Count how many zeros are in the string. | |
| let zeroCount = 0; | |
| for (const ch of s) { | |
| if (ch === '0') zeroCount++; | |
| } | |
| // Special case: flipping all bits each time. | |
| // If k == n, every operation inverts the entire string. | |
| if (n === k) { | |
| if (zeroCount === 0) return 0; // already all ones | |
| if (zeroCount === n) return 1; // all zeros → one flip makes all ones | |
| return -1; // mixed bits → impossible to reach all ones | |
| } | |
| // Helper for ceiling division: ceil(x / y) | |
| const ceilDiv = (x, y) => Math.floor((x + y - 1) / y); | |
| const INF = 1e18; | |
| let answer = INF; | |
| /** | |
| * CASE 1: zeroCount % 2 == 0 | |
| * | |
| * If the number of zeros is even, we can try to eliminate zeros by flipping | |
| * zeros in batches of size k, but we must also ensure that flipping ones | |
| * doesn't reintroduce zeros too quickly. The required number of operations | |
| * must also have even parity to maintain consistency. | |
| */ | |
| if (zeroCount % 2 === 0) { | |
| // Minimum operations needed based on how many zeros we can eliminate per step | |
| let ops = Math.max( | |
| ceilDiv(zeroCount, k), // enough flips to remove all zeros | |
| ceilDiv(zeroCount, n - k) // ensure ones flipped to zero can be repaired | |
| ); | |
| // ops must be even to match parity constraints | |
| if (ops % 2 === 1) ops++; | |
| answer = Math.min(answer, ops); | |
| } | |
| /** | |
| * CASE 2: zeroCount % 2 == k % 2 | |
| * | |
| * If the parity of zeroCount matches the parity of k, then after one operation | |
| * the zero count becomes even, and we can use the same reasoning as Case 1. | |
| * This branch handles the scenario where the first flip changes parity. | |
| */ | |
| if (zeroCount % 2 === (k % 2)) { | |
| let ops = Math.max( | |
| ceilDiv(zeroCount, k), // flips to reduce zeros | |
| ceilDiv(n - zeroCount, n - k) // flips to avoid reintroducing zeros | |
| ); | |
| // ops must be odd to match the required parity transition | |
| if (ops % 2 === 0) ops++; | |
| answer = Math.min(answer, ops); | |
| } | |
| return answer < INF ? answer : -1; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment