[亚麻高频题] Leetcode.926 Flip String to Monotone Increasing

题目链接&描述

Leetcode 926:求将一个01字符串反转成单调递增的最小反转次数

题目思路

1. 前缀后缀和

整体思路比较清晰好懂,每一个位置上形成单调递增字符串的反转次数=前面1的个数 + 后面0的个数。这样就可以转化成000...111的形式。所以我们只需维护一个数组记录每一个位置前面1的个数和每一个位置后面0的个数即可,代码如下:

public int minFlipsMonoIncr(String s) {
    
    int n = s.length();
    int[] pre1 = new int[n+1];
    
    for(int i=1; i<=n; i++) {
        pre1[i] = pre1[i-1] + s.charAt(i-1)-'0';
    }

    int res = n;
    // 后面的0的个数可以通过前缀和求差的方式得到 n-j - (pre1[n] - pre1[j])
    for(int i=0; i<=n; i++) {
        res = Math.min(res, pre1[i]+n-i+(pre1[n]-pre1[i]));
    }

    return res;
}

每一个位置后面0的个数可以通过前缀1的个数求差获得,整体算法时间复杂度:O(N) ;空间复杂度: O(N)

2. 动态规划

另一种思路是通过DP,我们建立一个二维DP数组dp[i][0]表示前i-1个元素单调递增且第i个元素为0需要的最小反转次数,dp[i][1]表示前i个元素单调递增且第i个元素为1需要的最小反转次数。定义好状态,接下来需要定义转移方程,分两种情况:

1.如果考虑将当前位置变化转化成0形成递增,那么该位置的状态就依赖于前面dp[0]的状态,因为要保证前面全0才能单调递增

dp[i][0] = dp[i-1][0] + (nums[i]==1?)

2.如果考虑将当前位置变化转化成1形成递增,那么比较灵活,前面可以为0或者1,那么该位置dp[1]的状态应该是前面的较小值min(dp[i-1][0], dp[i-1][1])就可以保证单调递增

dp[i][1] = min(dp[i-1][0], dp[i-1][1]) + (nums[i]==0?)

整体代码如下: 时间复杂度:O(N) 比前缀和算法少了一次循环;空间复杂度:O(N)。空间可以优化成O(1),因为每一次状态更新只依赖前面的状态,无需使用数组,这里用数组便于理解。

 public int minFlipsMonoIncr(String s) {
        // 状态 - dp[i][0/1] 前i-1个元素单调递增且当前为转化为0、1的最小反转次数
        int n = s.length();
        int[][] dp = new int[n][2];
        
        // 初始化
        dp[0][0] = s.charAt(0)=='1'? 1:0;
        dp[0][1] = s.charAt(0)=='0'? 1:0;

        for(int i=1; i<n; i++) {
            dp[i][0] = dp[i-1][0] + (s.charAt(i)=='1'?1:0);
            // 如果当前为转化成1 那么前面可以0递增也可1递增取最小
            dp[i][1] = Math.min(dp[i-1][1], dp[i-1][0]) + (s.charAt(i)=='0'? 1:0);
            
        }

        
        return Math.min(dp[n-1][0], dp[n-1][1]);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值