|
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