题目
![](https://img-blog.csdnimg.cn/img_convert/69684ed4d85f904b9c243b5e6961c931.png)
思路
我们要求解的字符串具有的性质是,存在一个位于s[i],s[i+1]之前的位置,这个位置左边的字符全为0,右边的字符全是1 。我们可以通过翻转某些值构造出一个满足上述性质的字符串,所以我们要找的就是这样一个位置,使得它左边1的数目加上右边0的数目最小。
代码
class Solution {
private:
int* pre;
public:
int minFlipsMonoIncr(string s) {
pre = new int[s.size()+1];
pre[0] = 0;
for(int i = 0; i < s.size(); ++i) {
pre[i+1] = pre[i]+s[i]-'0';
}
int _min = INT_MAX;
for(int i = -1; i < (int)s.size(); ++i) { // 从-1开始是因为这个位置可能位于所有字符之前
// 由于s.size()返回的是无符号数,所以要强制类型转换
int t = s.size()-(i+1);
t -= (pre[s.size()]-pre[i+1]);
_min = min(_min, pre[i+1]+t);
/* printf("%d %d\n", pre[i+1], t); */
}
return _min;
}
};
class Solution { // 刚发现我sb了,下面这样都不用计算前缀和,思维定式可太可怕了
public:
int minFlipsMonoIncr(string s) {
int lo = 0, rz = 0;
for(int i = 0; i < s.size(); ++i) {
if(s[i]=='0') ++rz;
}
int _min = lo+rz;
for(int i = 0; i < s.size(); ++i) {
if(s[i]=='1') {
lo += 1;
} else {
rz -= 1;
}
_min = min(lo+rz, _min);
}
return _min;
}
};