剑指offer 专项突破版 92、翻转字符

题目链接

思路
  • 假设f(i)为前i个字符有序的最小翻转数,那么f(i)和f(i-1)的数目关系要分情况讨论,如果f(i-1)以0结尾,那么f(i)可以以0结尾,也可以以1结尾;相反,如果f(i-1)以1结尾,那么f(i)必须以1结尾
  • 因此可以假设f(i)为前i个字符有序且以1结尾的最小翻转数、g(i)为前i个字符有序且以0结尾的最小翻转数
  • 那么状态转换方程为:
    • s[i] = 1 时 g(i)=g(i-1)+1 f(i)=min{f(i-1),g(i-1)}
    • s[i] = 0 时 g(i)=g(i-1) f(i)=min{f(i-1),g(i-1)}+1
    • 解释一波~ 对于g(i)来说,如果s[i]=0,那么g(i)不用翻转,且因为g(i)表示最终子串以0结尾,所以前一位(第i-1位)只能是0所以g(i)=g(i-1);如果s[i]=1,那么g(i)需要翻转,所以g(i)=g(i-1) + 1
    • 对于f(i)来说,如果s[i]=0,那么f(i)必须要翻转,但是此时前i-1位可以以0结尾,也可以以1结尾,所以有f(i)=min{f(i-1),g(i-1)}+1;那么当s[i]=1时,f(i)不需要翻转,所以f(i)=min{f(i-1),g(i-1)}
class Solution {
    public int minFlipsMonoIncr(String s) {

        // 第0列代表翻转成以0结尾的字符串 第1列代表翻转成以1结尾的字符串
        int[][] dp = new int[2][2];
        dp[0][0] = s.charAt(0) == '0' ? 0 : 1;
        dp[0][1] = 1 - dp[0][0];

        for (int i = 1; i < s.length(); i++) {
            char ch = s.charAt(i);
            dp[i % 2][0] = dp[(i - 1) % 2][0] + (ch == '0' ? 0 : 1);
            dp[i % 2][1] = Math.min(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1]) + (ch == '1' ? 0 : 1); 
        }
        return Math.min(dp[(s.length() - 1) % 2][0], dp[(s.length() - 1) % 2][1]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值