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
6167class Solution :
6268 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)
7274 return ans
7375```
7476
7577``` java
7678class 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 {
97100class Solution {
98101public:
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
118115func 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 */
146148var 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