53
53
54
54
<!-- 这里可写通用的实现逻辑 -->
55
55
56
- 我们需要找到一个分界点 ` i ` ,使 ` [:i] ` 全为 0,` [i:] ` 全为 1,并且翻转次数最少,问题就转换成计算 ` i ` 的左右两侧的翻转次数,可以用前缀和进行优化
56
+ ** 方法一:枚举**
57
+
58
+ 我们先预处理得到右侧的 $0$ 的个数,记为 $right0$,初始化一个变量 $left0$,表示左侧的 $0$ 的个数。如果最终字符串变成全 ` '0' ` 或者全 ` '1' ` ,那么答案为 $ans= \min(right0, n - right0)$。
59
+
60
+ 接下来,我们枚举每个位置作为 ` '0' ` 和 ` '1' ` 的分界点(约定分界点为 ` '0' ` ),计算出以当前位置为分界点的答案,最后取最小值即可。
61
+
62
+ 时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。
57
63
58
64
<!-- tabs:start -->
59
65
64
70
``` python
65
71
class Solution :
66
72
def minFlipsMonoIncr (self , s : str ) -> int :
73
+ left0, right0 = 0 , s.count(" 0" )
67
74
n = len (s)
68
- left, right = [0 ] * (n + 1 ), [0 ] * (n + 1 )
69
- ans = 0x 3F3F3F3F
70
- for i in range (1 , n + 1 ):
71
- left[i] = left[i - 1 ] + (1 if s[i - 1 ] == ' 1' else 0 )
72
- for i in range (n - 1 , - 1 , - 1 ):
73
- right[i] = right[i + 1 ] + (1 if s[i] == ' 0' else 0 )
74
- for i in range (0 , n + 1 ):
75
- ans = min (ans, left[i] + right[i])
75
+ ans = min (right0, n - right0)
76
+ for i, c in enumerate (s, 1 ):
77
+ x = int (c)
78
+ right0 -= x ^ 1
79
+ left0 += x ^ 1
80
+ ans = min (ans, i - left0 + right0)
76
81
return ans
77
82
```
78
83
@@ -84,17 +89,18 @@ class Solution:
84
89
class Solution {
85
90
public int minFlipsMonoIncr (String s ) {
86
91
int n = s. length();
87
- int [] left = new int [n + 1 ];
88
- int [] right = new int [n + 1 ];
89
- int ans = Integer . MAX_VALUE ;
90
- for (int i = 1 ; i <= n; i++ ) {
91
- left[i] = left[i - 1 ] + (s. charAt(i - 1 ) == ' 1' ? 1 : 0 );
92
- }
93
- for (int i = n - 1 ; i >= 0 ; i-- ) {
94
- right[i] = right[i + 1 ] + (s. charAt(i) == ' 0' ? 1 : 0 );
92
+ int left0 = 0 , right0 = 0 ;
93
+ for (int i = 0 ; i < n; ++ i) {
94
+ if (s. charAt(i) == ' 0' ) {
95
+ ++ right0;
96
+ }
95
97
}
96
- for (int i = 0 ; i <= n; i++ ) {
97
- ans = Math . min(ans, left[i] + right[i]);
98
+ int ans = Math . min(right0, n - right0);
99
+ for (int i = 1 ; i <= n; ++ i) {
100
+ int x = s. charAt(i - 1 ) == ' 0' ? 0 : 1 ;
101
+ right0 -= x ^ 1 ;
102
+ left0 += x ^ 1 ;
103
+ ans = Math . min(ans, i - left0 + right0);
98
104
}
99
105
return ans;
100
106
}
@@ -108,16 +114,16 @@ class Solution {
108
114
public:
109
115
int minFlipsMonoIncr(string s) {
110
116
int n = s.size();
111
- vector<int > left(n + 1, 0), right(n + 1, 0);
112
- int ans = INT_MAX;
113
- for (int i = 1; i <= n; ++i) {
114
- left[ i] = left[ i - 1] + (s[ i - 1] == '1');
117
+ int left0 = 0, right0 = 0;
118
+ for (char& c : s) {
119
+ right0 += c == '0';
115
120
}
116
- for (int i = n - 1; i >= 0; --i) {
117
- right[ i] = right[ i + 1] + (s[ i] == '0');
118
- }
119
- for (int i = 0; i <= n; i++) {
120
- ans = min(ans, left[ i] + right[ i] );
121
+ int ans = min(right0, n - right0);
122
+ for (int i = 1; i <= n; ++i) {
123
+ int x = s[ i - 1] == '1';
124
+ right0 -= x ^ 1;
125
+ left0 += x ^ 1;
126
+ ans = min(ans, i - left0 + right0);
121
127
}
122
128
return ans;
123
129
}
@@ -129,31 +135,50 @@ public:
129
135
```go
130
136
func minFlipsMonoIncr(s string) int {
131
137
n := len(s)
132
- left, right := make([]int, n+1), make([]int, n+1)
133
- ans := math.MaxInt32
134
- for i := 1; i <= n; i++ {
135
- left[i] = left[i-1]
136
- if s[i-1] == '1' {
137
- left[i]++
138
+ left0, right0 := 0, 0
139
+ for _, c := range s {
140
+ if c == '0' {
141
+ right0++
138
142
}
139
143
}
140
- for i := n - 1; i >= 0; i-- {
141
- right[i] = right[i+1]
142
- if s[i] == '0' {
143
- right[i]++
144
+ ans := min(right0, n-right0)
145
+ for i, c := range s {
146
+ x := 0
147
+ if c == '1' {
148
+ x = 1
144
149
}
145
- }
146
- for i := 0; i <= n; i++ {
147
- ans = min(ans, left[i]+right[i] )
150
+ right0 -= x ^ 1
151
+ left0 += x ^ 1
152
+ ans = min(ans, i+1-left0+right0 )
148
153
}
149
154
return ans
150
155
}
151
156
152
- func min(x, y int) int {
153
- if x < y {
154
- return x
157
+ func min(a, b int) int {
158
+ if a < b {
159
+ return a
155
160
}
156
- return y
161
+ return b
162
+ }
163
+ ```
164
+
165
+ ### ** TypeScript**
166
+
167
+ ``` ts
168
+ function minFlipsMonoIncr(s : string ): number {
169
+ const n = s .length ;
170
+ let [left0, right0] = [0 , 0 ];
171
+ for (const c of s ) {
172
+ right0 += c === ' 0' ? 1 : 0 ;
173
+ }
174
+ let ans = Math .min (right0 , n - right0 );
175
+ for (let i = 1 ; i <= n ; ++ i ) {
176
+ const x = s [i - 1 ] === ' 0' ? 0 : 1 ;
177
+ right0 -= x ^ 1 ;
178
+ left0 += x ^ 1 ;
179
+ ans = Math .min (ans , i - left0 + right0 );
180
+ }
181
+ return ans ;
157
182
}
158
183
```
159
184
0 commit comments