51
51
52
52
## 解法
53
53
54
- ### 方法一:前缀和
54
+ ### 方法一:前缀和 + 枚举
55
55
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)$。
57
63
58
64
<!-- tabs:start -->
59
65
60
66
``` python
61
67
class Solution :
62
68
def minFlipsMonoIncr (self , s : str ) -> int :
63
- n = len (s)
64
- left, right = [0 ] * (n + 1 ), [0 ] * (n + 1 )
65
- ans = 0x 3F3F3F3F
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)
72
74
return ans
73
75
```
74
76
75
77
``` java
76
78
class Solution {
77
79
public int minFlipsMonoIncr (String s ) {
78
80
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
+ }
87
86
}
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);
90
93
}
91
94
return ans;
92
95
}
@@ -97,17 +100,11 @@ class Solution {
97
100
class Solution {
98
101
public:
99
102
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);
111
108
}
112
109
return ans;
113
110
}
@@ -116,112 +113,52 @@ public:
116
113
117
114
```go
118
115
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++
132
121
}
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)
136
123
}
137
124
return ans
138
125
}
139
126
```
140
127
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
+
141
143
``` js
142
144
/**
143
145
* @param {string} s
144
146
* @return {number}
145
147
*/
146
148
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 ;
151
152
}
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);
155
157
}
156
158
return ans;
157
159
};
158
160
```
159
161
160
162
<!-- tabs: end -->
161
163
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
-
227
164
<!-- end -->
0 commit comments