LeetCode-926 flip-string-to-monotone-increasing 字符串翻转到单调递增

版权声明:转载请注明原址,有错误欢迎指出 https://blog.csdn.net/iwts_24/article/details/83346294

题目链接

LeetCode 周赛 107场 B题

https://leetcode-cn.com/contest/weekly-contest-107/problems/flip-string-to-monotone-increasing/

题意

中文题,这个递增允许不变,例如全0或者全1也是按照递增处理。

题解

        智障了= =竟然拖很长时间才做出来。刚开始想使用暴力(绝壁TLE),想到了使用DFS,即从第一个字符开始,如果是0,那么有翻转或者不翻转两种可能,再往下搜索时判定上一位是0还是1,如果是0那么这一位可以翻转可以不翻转,如果是1,那么这一位就只能翻转。

        这样DFS而不考虑剪枝的话是TLE的。后来想了一下,全0或者全1的情况排除,只剩下一种情况:以i点为轴,左边全为0,右边全为1。这样在极限的情况下就是全0或者全1的情况。那么可以这样考虑:以i为轴,i左边所有的数1翻转为0,右边的数0翻转成1。这样在代码上,可以先遍历一次字符串,统计0或者1的总数,第二次遍历,建立一个数组,储存该点左边有几个0或者1。第三次遍历,根据上面获得的变量利用数学推导(解一元方程而已)计算出来翻转次数。这样在O(n)的时间复杂度上解决该问题。

Java 代码

class Solution {
    public static int Min(int a,int b){
        return a > b ? b : a;
    }
    
    public int minFlipsMonoIncr(String S) {
        int len = S.length();
        int num0 = 0;
        int[] left0 = new int[len];
        for(int i = 0;i < len;i++){
            if(S.charAt(i) == '0'){
                num0++;
            }
        }
        if(S.charAt(0) == '0'){
            left0[0] = 1;
        }else{
            left0[0] = 0;
        }
        for(int i = 1;i < len;i++){
            left0[i] = left0[i-1];
            if(S.charAt(i) == '0'){
                left0[i]++;
            }
        }
        int ans = Min(num0,(len - num0));
        for(int i = 0;i < len;i++){
            int now = i+1+num0-2*left0[i];
            ans = Min(ans,now);
        }
        return ans;
    }
}

猜你喜欢

转载自blog.csdn.net/iwts_24/article/details/83346294