|
1 | 1 | package g3601_3700.s3666_minimum_operations_to_equalize_binary_string;
|
2 | 2 |
|
3 |
| -// #Hard #Biweekly_Contest_164 #2025_09_06_Time_4_ms_(100.00%)_Space_46.11_MB_(31.99%) |
| 3 | +// #Hard #Biweekly_Contest_164 #2025_09_06_Time_6_ms_(83.87%)_Space_45.74_MB_(64.52%) |
4 | 4 |
|
5 | 5 | public class Solution {
|
6 | 6 | public int minOperations(String s, int k) {
|
7 |
| - int zero = 0; |
8 |
| - for (char chr : s.toCharArray()) { |
9 |
| - zero += '1' - chr; |
10 |
| - } |
11 |
| - if (zero % 2 != 0 && k % 2 == 0) { |
12 |
| - return -1; |
13 |
| - } |
14 |
| - if (zero % k == 0) { |
15 |
| - return zero / k; |
| 7 | + int n = s.length(); |
| 8 | + int cnt0 = 0; |
| 9 | + for (char c : s.toCharArray()) { |
| 10 | + if (c == '0') { |
| 11 | + cnt0++; |
| 12 | + } |
16 | 13 | }
|
17 |
| - if (k % 2 == 0) { |
18 |
| - return get(zero, s.length(), k); |
19 |
| - } else { |
20 |
| - return get1(zero, s.length(), k); |
| 14 | + if (cnt0 == 0) { |
| 15 | + return 0; |
21 | 16 | }
|
22 |
| - } |
23 |
| - |
24 |
| - private int get(int zero, int sum, int k) { |
25 |
| - int l = zero; |
26 |
| - int r = zero; |
27 |
| - int res = 0; |
28 |
| - while (true) { |
29 |
| - if (l == 0) { |
30 |
| - return res; |
31 |
| - } |
32 |
| - int lNext; |
33 |
| - if (l >= k) { |
34 |
| - lNext = l - k; |
35 |
| - } else if (r >= k) { |
36 |
| - lNext = 0; |
37 |
| - } else { |
38 |
| - lNext = k - r; |
39 |
| - } |
40 |
| - int rNext; |
41 |
| - int a = sum - r; |
42 |
| - int b = sum - l; |
43 |
| - if (a >= k) { |
44 |
| - rNext = r + k; |
45 |
| - } else if (b >= k) { |
46 |
| - rNext = sum; |
47 |
| - } else { |
48 |
| - rNext = l + b - (k - b); |
49 |
| - } |
50 |
| - if (l == lNext && r == rNext) { |
51 |
| - break; |
52 |
| - } |
53 |
| - if (l > lNext) { |
54 |
| - l = lNext; |
55 |
| - } |
56 |
| - if (r < rNext) { |
57 |
| - r = rNext; |
58 |
| - } |
59 |
| - res++; |
| 17 | + if (k == n) { |
| 18 | + return cnt0 == n ? 1 : -1; |
60 | 19 | }
|
61 |
| - return -1; |
62 |
| - } |
63 |
| - |
64 |
| - private int get1(int zero, int sum, int k) { |
65 |
| - int[] l = {Integer.MAX_VALUE, zero}; |
66 |
| - int[] r = {Integer.MIN_VALUE, zero}; |
67 |
| - int res = 0; |
68 |
| - while (true) { |
69 |
| - int idx1 = res % 2; |
70 |
| - int idx = 1 - idx1; |
71 |
| - int lNext; |
72 |
| - int offset = 1 - l[idx] % 2; |
73 |
| - if (l[idx] >= k) { |
74 |
| - lNext = l[idx] - k; |
75 |
| - } else if (r[idx] >= k) { |
76 |
| - lNext = offset; |
77 |
| - } else { |
78 |
| - lNext = k - r[idx]; |
79 |
| - } |
80 |
| - int rNext; |
81 |
| - int a = sum - r[idx]; |
82 |
| - int b = sum - l[idx]; |
83 |
| - if (a >= k) { |
84 |
| - rNext = r[idx] + k; |
85 |
| - } else if (b >= k) { |
86 |
| - rNext = sum - offset; |
87 |
| - } else { |
88 |
| - rNext = l[idx] + b - (k - b); |
89 |
| - } |
90 |
| - if (l[idx1] == lNext && r[idx1] == rNext) { |
91 |
| - break; |
92 |
| - } |
93 |
| - if (l[idx1] > lNext) { |
94 |
| - l[idx1] = lNext; |
95 |
| - } |
96 |
| - if (r[idx1] < rNext) { |
97 |
| - r[idx1] = rNext; |
98 |
| - } |
99 |
| - res++; |
100 |
| - if (l[idx1] == 0) { |
101 |
| - return res; |
| 20 | + int kP = k & 1; |
| 21 | + int needP = cnt0 & 1; |
| 22 | + long best = Long.MAX_VALUE; |
| 23 | + for (int p = 0; p <= 1; p++) { |
| 24 | + if ((p * kP) % 2 != needP) { |
| 25 | + continue; |
| 26 | + } |
| 27 | + long mismatch = (p == 0) ? cnt0 : (n - cnt0); |
| 28 | + long b1 = (cnt0 + k - 1L) / k; |
| 29 | + long b2; |
| 30 | + b2 = (mismatch + (n - k) - 1L) / (n - k); |
| 31 | + long lb = Math.max(b1, b2); |
| 32 | + if (lb < 1) { |
| 33 | + lb = 1; |
| 34 | + } |
| 35 | + if ((lb & 1) != p) { |
| 36 | + lb++; |
| 37 | + } |
| 38 | + if (lb < best) { |
| 39 | + best = lb; |
102 | 40 | }
|
103 | 41 | }
|
104 |
| - return -1; |
| 42 | + return best == Long.MAX_VALUE ? -1 : (int) best; |
105 | 43 | }
|
106 | 44 | }
|
0 commit comments