LeetCode/将字符串翻转到单调递增

如果一个二进制字符串,是以一些 0(可能没有 0)后面跟着一些 1(也可能没有 1)的形式组成的,那么该字符串是单调递增的
给你一个二进制字符串 s,你可以将任何 0 翻转为 1 或者将 1 翻转为 0
返回使 s 单调递增的最小翻转次数

1. 暴力法

遍历每一个位置,计算将该位置左侧全部置0,右侧全部置1所需要的翻转次数
最后求取对应翻转最小次数

暴力法
class Solution {
public:
    int minFlipsMonoIncr(string s) {
        int n = s.size();
        int res = INT_MAX;
        for(int i=0;i<=n;i++){
            int sum = 0;
            for(int j=0;j<i;j++)
                sum = sum + s[j]-'0';
            for(int j=i;j<n;j++)
                sum = sum + '1'-s[j];
        res = min(res,sum);
        }
        return res;
    }
};

2. 暴力法优化

事先计算出每个位置左右侧置0置1需要的翻转次数,避免重复计算

class Solution {
public:
    int minFlipsMonoIncr(string s) {
        int n = s.size();
        int res = INT_MAX;
        //因为很多重复计算,所以先把和计算出来
        vector<int> left(n+1);//left[i]存储i左侧置零需要的次数
        vector<int> right(n+1);//right[i]存储i右侧置一需要的次数
        left[0]=0;//位于最左侧无需修改任何值为0
        for(int j=1;j<=n;j++)
            left[j] = left[j-1] + s[j-1]-'0';
        right[n]=0;//由于最右侧无需修改任何值为1
        for(int j = n-1;j >=0;j--)
            right[j] = right[j+1] + '1'-s[j];
        for(int i=0;i<=n;i++)
            res = min(res,right[i]+left[i]);
        return res;
    }
};

3. 动态规划

dp[i]为使得0~i递增的最小翻转数
状态转移方程为
dp[i]=dp[i-1] if s[i]='1' //无需翻转
dp[i]= min(dp[i-1]+1,count) if s[i]='0' //count即把全部值变成0

class Solution {
public:
    int minFlipsMonoIncr(string s) {
        int dp = 0;
        int count = 0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='0')
                dp = min(dp+1,count);
            else count++;
        }
        return dp;
    }
};
posted @ 2022-06-11 02:26  失控D大白兔  阅读(33)  评论(0编辑  收藏  举报