Skip to content

Commit 94405ad

Browse files
authored
feat: add solutions to lc problem: No.0926 (#2594)
No.0926.Flip String to Monotone Increasing
1 parent be4747f commit 94405ad

File tree

14 files changed

+191
-341
lines changed

14 files changed

+191
-341
lines changed

solution/0900-0999/0926.Flip String to Monotone Increasing/README.md

+57-120
Original file line numberDiff line numberDiff line change
@@ -51,42 +51,45 @@
5151

5252
## 解法
5353

54-
### 方法一:前缀和
54+
### 方法一:前缀和 + 枚举
5555

56-
我们需要找到一个分界点 `i`,使 `[:i]` 全为 0,`[i:]` 全为 1,并且翻转次数最少,问题就转换成计算 `i` 的左右两侧的翻转次数,可以用前缀和进行优化。
56+
我们可以先统计字符串 $s$ 中 $0$ 的个数,记为 $tot$。定义一个答案变量 $ans$,初始时 $ans = tot$,表示将所有 $0$ 变成 $1$ 的翻转次数。
57+
58+
然后,我们可以枚举每个位置 $i$,将位置 $i$ 及其左边的所有 $1$ 变成 $0$,将位置 $i$ 右边的所有 $0$ 变成 $1$,计算这种情况下的翻转次数,即 $i + 1 - cur + tot - cur$,其中 $cur$ 表示位置 $i$ 及其左边的 $0$ 的个数,更新答案 $ans = \min(ans, i + 1 - cur + tot - cur)$。
59+
60+
最后返回答案 $ans$ 即可。
61+
62+
时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
5763

5864
<!-- tabs:start -->
5965

6066
```python
6167
class Solution:
6268
def minFlipsMonoIncr(self, s: str) -> int:
63-
n = len(s)
64-
left, right = [0] * (n + 1), [0] * (n + 1)
65-
ans = 0x3F3F3F3F
66-
for i in range(1, n + 1):
67-
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
68-
for i in range(n - 1, -1, -1):
69-
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
70-
for i in range(0, n + 1):
71-
ans = min(ans, left[i] + right[i])
69+
tot = s.count("0")
70+
ans, cur = tot, 0
71+
for i, c in enumerate(s, 1):
72+
cur += int(c == "0")
73+
ans = min(ans, i - cur + tot - cur)
7274
return ans
7375
```
7476

7577
```java
7678
class Solution {
7779
public int minFlipsMonoIncr(String s) {
7880
int n = s.length();
79-
int[] left = new int[n + 1];
80-
int[] right = new int[n + 1];
81-
int ans = Integer.MAX_VALUE;
82-
for (int i = 1; i <= n; i++) {
83-
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
84-
}
85-
for (int i = n - 1; i >= 0; i--) {
86-
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
81+
int tot = 0;
82+
for (int i = 0; i < n; ++i) {
83+
if (s.charAt(i) == '0') {
84+
++tot;
85+
}
8786
}
88-
for (int i = 0; i <= n; i++) {
89-
ans = Math.min(ans, left[i] + right[i]);
87+
int ans = tot, cur = 0;
88+
for (int i = 1; i <= n; ++i) {
89+
if (s.charAt(i - 1) == '0') {
90+
++cur;
91+
}
92+
ans = Math.min(ans, i - cur + tot - cur);
9093
}
9194
return ans;
9295
}
@@ -97,17 +100,11 @@ class Solution {
97100
class Solution {
98101
public:
99102
int minFlipsMonoIncr(string s) {
100-
int n = s.size();
101-
vector<int> left(n + 1, 0), right(n + 1, 0);
102-
int ans = INT_MAX;
103-
for (int i = 1; i <= n; ++i) {
104-
left[i] = left[i - 1] + (s[i - 1] == '1');
105-
}
106-
for (int i = n - 1; i >= 0; --i) {
107-
right[i] = right[i + 1] + (s[i] == '0');
108-
}
109-
for (int i = 0; i <= n; i++) {
110-
ans = min(ans, left[i] + right[i]);
103+
int tot = count(s.begin(), s.end(), '0');
104+
int ans = tot, cur = 0;
105+
for (int i = 1; i <= s.size(); ++i) {
106+
cur += s[i - 1] == '0';
107+
ans = min(ans, i - cur + tot - cur);
111108
}
112109
return ans;
113110
}
@@ -116,112 +113,52 @@ public:
116113
117114
```go
118115
func minFlipsMonoIncr(s string) int {
119-
n := len(s)
120-
left, right := make([]int, n+1), make([]int, n+1)
121-
ans := math.MaxInt32
122-
for i := 1; i <= n; i++ {
123-
left[i] = left[i-1]
124-
if s[i-1] == '1' {
125-
left[i]++
126-
}
127-
}
128-
for i := n - 1; i >= 0; i-- {
129-
right[i] = right[i+1]
130-
if s[i] == '0' {
131-
right[i]++
116+
tot := strings.Count(s, "0")
117+
ans, cur := tot, 0
118+
for i, c := range s {
119+
if c == '0' {
120+
cur++
132121
}
133-
}
134-
for i := 0; i <= n; i++ {
135-
ans = min(ans, left[i]+right[i])
122+
ans = min(ans, i+1-cur+tot-cur)
136123
}
137124
return ans
138125
}
139126
```
140127

128+
```ts
129+
function minFlipsMonoIncr(s: string): number {
130+
let tot = 0;
131+
for (const c of s) {
132+
tot += c === '0' ? 1 : 0;
133+
}
134+
let [ans, cur] = [tot, 0];
135+
for (let i = 1; i <= s.length; ++i) {
136+
cur += s[i - 1] === '0' ? 1 : 0;
137+
ans = Math.min(ans, i - cur + tot - cur);
138+
}
139+
return ans;
140+
}
141+
```
142+
141143
```js
142144
/**
143145
* @param {string} s
144146
* @return {number}
145147
*/
146148
var minFlipsMonoIncr = function (s) {
147-
const n = s.length;
148-
let presum = new Array(n + 1).fill(0);
149-
for (let i = 0; i < n; ++i) {
150-
presum[i + 1] = presum[i] + (s[i] == '1');
149+
let tot = 0;
150+
for (const c of s) {
151+
tot += c === '0' ? 1 : 0;
151152
}
152-
let ans = presum[n];
153-
for (let i = 0; i < n; ++i) {
154-
ans = Math.min(ans, presum[i] + n - i - (presum[n] - presum[i]));
153+
let [ans, cur] = [tot, 0];
154+
for (let i = 1; i <= s.length; ++i) {
155+
cur += s[i - 1] === '0' ? 1 : 0;
156+
ans = Math.min(ans, i - cur + tot - cur);
155157
}
156158
return ans;
157159
};
158160
```
159161

160162
<!-- tabs:end -->
161163

162-
### 方法二
163-
164-
<!-- tabs:start -->
165-
166-
```python
167-
class Solution:
168-
def minFlipsMonoIncr(self, s: str) -> int:
169-
n = len(s)
170-
presum = [0] * (n + 1)
171-
for i, c in enumerate(s):
172-
presum[i + 1] = presum[i] + int(c)
173-
ans = presum[-1]
174-
for i in range(n):
175-
ans = min(ans, presum[i] + n - i - (presum[-1] - presum[i]))
176-
return ans
177-
```
178-
179-
```java
180-
class Solution {
181-
public int minFlipsMonoIncr(String s) {
182-
int n = s.length();
183-
int[] presum = new int[n + 1];
184-
for (int i = 0; i < n; ++i) {
185-
presum[i + 1] = presum[i] + (s.charAt(i) - '0');
186-
}
187-
int ans = presum[n];
188-
for (int i = 0; i < n; ++i) {
189-
ans = Math.min(ans, presum[i] + n - i - (presum[n] - presum[i]));
190-
}
191-
return ans;
192-
}
193-
}
194-
```
195-
196-
```cpp
197-
class Solution {
198-
public:
199-
int minFlipsMonoIncr(string s) {
200-
int n = s.size();
201-
vector<int> presum(n + 1);
202-
for (int i = 0; i < n; ++i) presum[i + 1] = presum[i] + (s[i] == '1');
203-
int ans = presum[n];
204-
for (int i = 0; i < n; ++i) ans = min(ans, presum[i] + n - i - (presum[n] - presum[i]));
205-
return ans;
206-
}
207-
};
208-
```
209-
210-
```go
211-
func minFlipsMonoIncr(s string) int {
212-
n := len(s)
213-
presum := make([]int, n+1)
214-
for i, c := range s {
215-
presum[i+1] = presum[i] + int(c-'0')
216-
}
217-
ans := presum[n]
218-
for i := range s {
219-
ans = min(ans, presum[i]+n-i-(presum[n]-presum[i]))
220-
}
221-
return ans
222-
}
223-
```
224-
225-
<!-- tabs:end -->
226-
227164
<!-- end -->

0 commit comments

Comments
 (0)