Skip to content

Commit 89b48f7

Browse files
authored
feat: add solutions to lc problem: No.1864 (#4039)
No.1864.Minimum Number of Swaps to Make the Binary String Alternating
1 parent 179f91b commit 89b48f7

File tree

8 files changed

+425
-178
lines changed

8 files changed

+425
-178
lines changed

solution/1800-1899/1864.Minimum Number of Swaps to Make the Binary String Alternating/README.md

Lines changed: 151 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,21 @@ tags:
6565

6666
<!-- solution:start -->
6767

68-
### 方法一
68+
### 方法一:计数
69+
70+
我们先统计字符串 $\textit{s}$ 中字符 $0$ 和字符 $1$ 的个数,分别记为 $n_0$ 和 $n_1$。
71+
72+
如果 $n_0$ 和 $n_1$ 的绝对值大于 $1$,那么无法构成交替字符串,返回 $-1$。
73+
74+
如果 $n_0$ 和 $n_1$ 相等,那么我们可以分别计算将字符串转化为以 $0$ 开头和以 $1$ 开头的交替字符串所需要的交换次数,取最小值。
75+
76+
如果 $n_0$ 和 $n_1$ 不相等,那么我们只需要计算将字符串转化为以字符个数较多的字符开头的交替字符串所需要的交换次数。
77+
78+
问题转换为:计算字符串 $\textit{s}$ 转化为以字符 $c$ 开头的交替字符串所需要的交换次数。
79+
80+
我们定义一个函数 $\text{calc}(c)$,表示将字符串 $\textit{s}$ 转化为以字符 $c$ 开头的交替字符串所需要的交换次数。我们遍历字符串 $\textit{s}$,对于每个位置 $i$,如果 $i$ 与 $c$ 的奇偶性不同,那么我们需要交换这个位置的字符,计数器 $+1$。由于每次交换都会使两个位置的字符变得相同,因此最终的交换次数为计数器的一半。
81+
82+
时间复杂度 $O(n)$,其中 $n$ 是字符串 $\textit{s}$ 的长度。空间复杂度 $O(1)$。
6983

7084
<!-- tabs:start -->
7185

@@ -74,60 +88,141 @@ tags:
7488
```python
7589
class Solution:
7690
def minSwaps(self, s: str) -> int:
77-
s0n0 = s0n1 = s1n0 = s1n1 = 0
78-
for i in range(len(s)):
79-
if (i & 1) == 0:
80-
if s[i] != '0':
81-
s0n0 += 1
82-
else:
83-
s1n1 += 1
84-
else:
85-
if s[i] != '0':
86-
s1n0 += 1
87-
else:
88-
s0n1 += 1
89-
if s0n0 != s0n1 and s1n0 != s1n1:
91+
def calc(c: int) -> int:
92+
return sum((c ^ i & 1) != x for i, x in enumerate(map(int, s))) // 2
93+
94+
n0 = s.count("0")
95+
n1 = len(s) - n0
96+
if abs(n0 - n1) > 1:
9097
return -1
91-
if s0n0 != s0n1:
92-
return s1n0
93-
if s1n0 != s1n1:
94-
return s0n0
95-
return min(s0n0, s1n0)
98+
if n0 == n1:
99+
return min(calc(0), calc(1))
100+
return calc(0 if n0 > n1 else 1)
96101
```
97102

98103
#### Java
99104

100105
```java
101106
class Solution {
107+
private char[] s;
108+
102109
public int minSwaps(String s) {
103-
int s0n0 = 0, s0n1 = 0;
104-
int s1n0 = 0, s1n1 = 0;
105-
for (int i = 0; i < s.length(); ++i) {
106-
if ((i & 1) == 0) {
107-
if (s.charAt(i) != '0') {
108-
s0n0 += 1;
109-
} else {
110-
s1n1 += 1;
111-
}
112-
} else {
113-
if (s.charAt(i) != '0') {
114-
s1n0 += 1;
115-
} else {
116-
s0n1 += 1;
117-
}
110+
this.s = s.toCharArray();
111+
int n1 = 0;
112+
for (char c : this.s) {
113+
n1 += (c - '0');
114+
}
115+
int n0 = this.s.length - n1;
116+
if (Math.abs(n0 - n1) > 1) {
117+
return -1;
118+
}
119+
if (n0 == n1) {
120+
return Math.min(calc(0), calc(1));
121+
}
122+
return calc(n0 > n1 ? 0 : 1);
123+
}
124+
125+
private int calc(int c) {
126+
int cnt = 0;
127+
for (int i = 0; i < s.length; ++i) {
128+
int x = s[i] - '0';
129+
if ((i & 1 ^ c) != x) {
130+
++cnt;
118131
}
119132
}
120-
if (s0n0 != s0n1 && s1n0 != s1n1) {
133+
return cnt / 2;
134+
}
135+
}
136+
```
137+
138+
#### C++
139+
140+
```cpp
141+
class Solution {
142+
public:
143+
int minSwaps(string s) {
144+
int n0 = ranges::count(s, '0');
145+
int n1 = s.size() - n0;
146+
if (abs(n0 - n1) > 1) {
121147
return -1;
122148
}
123-
if (s0n0 != s0n1) {
124-
return s1n0;
149+
auto calc = [&](int c) -> int {
150+
int cnt = 0;
151+
for (int i = 0; i < s.size(); ++i) {
152+
int x = s[i] - '0';
153+
if ((i & 1 ^ c) != x) {
154+
++cnt;
155+
}
156+
}
157+
return cnt / 2;
158+
};
159+
if (n0 == n1) {
160+
return min(calc(0), calc(1));
125161
}
126-
if (s1n0 != s1n1) {
127-
return s0n0;
162+
return calc(n0 > n1 ? 0 : 1);
163+
}
164+
};
165+
```
166+
167+
#### Go
168+
169+
```go
170+
func minSwaps(s string) int {
171+
n0 := strings.Count(s, "0")
172+
n1 := len(s) - n0
173+
if abs(n0-n1) > 1 {
174+
return -1
175+
}
176+
calc := func(c int) int {
177+
cnt := 0
178+
for i, ch := range s {
179+
x := int(ch - '0')
180+
if i&1^c != x {
181+
cnt++
182+
}
183+
}
184+
return cnt / 2
185+
}
186+
if n0 == n1 {
187+
return min(calc(0), calc(1))
188+
}
189+
if n0 > n1 {
190+
return calc(0)
191+
}
192+
return calc(1)
193+
}
194+
195+
func abs(x int) int {
196+
if x < 0 {
197+
return -x
198+
}
199+
return x
200+
}
201+
```
202+
203+
#### TypeScript
204+
205+
```ts
206+
function minSwaps(s: string): number {
207+
const n0 = (s.match(/0/g) || []).length;
208+
const n1 = s.length - n0;
209+
if (Math.abs(n0 - n1) > 1) {
210+
return -1;
211+
}
212+
const calc = (c: number): number => {
213+
let cnt = 0;
214+
for (let i = 0; i < s.length; i++) {
215+
const x = +s[i];
216+
if (((i & 1) ^ c) !== x) {
217+
cnt++;
218+
}
128219
}
129-
return Math.min(s0n0, s1n0);
220+
return Math.floor(cnt / 2);
221+
};
222+
if (n0 === n1) {
223+
return Math.min(calc(0), calc(1));
130224
}
225+
return calc(n0 > n1 ? 0 : 1);
131226
}
132227
```
133228

@@ -139,28 +234,25 @@ class Solution {
139234
* @return {number}
140235
*/
141236
var minSwaps = function (s) {
142-
let n = s.length;
143-
let n1 = [...s].reduce((a, c) => parseInt(c) + a, 0);
144-
let n0 = n - n1;
145-
let count = Infinity;
146-
let half = n / 2;
147-
// 101、1010
148-
if (n1 == Math.ceil(half) && n0 == Math.floor(half)) {
149-
let cur = 0;
150-
for (let i = 0; i < n; i++) {
151-
if (i % 2 == 0 && s.charAt(i) != '1') cur++;
152-
}
153-
count = Math.min(count, cur);
237+
const n0 = (s.match(/0/g) || []).length;
238+
const n1 = s.length - n0;
239+
if (Math.abs(n0 - n1) > 1) {
240+
return -1;
154241
}
155-
// 010、0101
156-
if (n0 == Math.ceil(half) && n1 == Math.floor(half)) {
157-
let cur = 0;
158-
for (let i = 0; i < n; i++) {
159-
if (i % 2 == 0 && s.charAt(i) != '0') cur++;
242+
const calc = c => {
243+
let cnt = 0;
244+
for (let i = 0; i < s.length; i++) {
245+
const x = +s[i];
246+
if (((i & 1) ^ c) !== x) {
247+
cnt++;
248+
}
160249
}
161-
count = Math.min(count, cur);
250+
return Math.floor(cnt / 2);
251+
};
252+
if (n0 === n1) {
253+
return Math.min(calc(0), calc(1));
162254
}
163-
return count == Infinity ? -1 : count;
255+
return calc(n0 > n1 ? 0 : 1);
164256
};
165257
```
166258

0 commit comments

Comments
 (0)