「LeetCode」926-将字符串翻转到单调递增

133 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

一.题目:

926. 将字符串翻转到单调递增 如果一个二进制字符串,是以一些 0(可能没有 0)后面跟着一些 1(也可能没有 1)的形式组成的,那么该字符串是 单调递增 的。

给你一个二进制字符串 s,你可以将任何 0 翻转为 1 或者将 1 翻转为 0 。

返回使 s 单调递增的最小翻转次数。 示例 1:

输入: s = "00110"
输出: 1
解释: 翻转最后一位得到 00111.

示例 2:

输入: s = "010110"
输出: 2
解释: 翻转得到 011111,或者是 000111。

示例 3:

输入: s = "00011000"
输出: 2
解释: 翻转得到 00000000。

提示:

  • 1 <= s.length <= 105
  • s[i] 为 '0' 或 '1'

二、思路分析:

首先看题目给定一个字符串s,要求我们能够最小的次数去使这个字符串是单调递增的,翻转的规则是从0变成1,也可以从1变成0。根据题目的要求我们得到最小的翻转次数,所以我们最好是通过统计每个位置的反转次数来得到最终的结果。基本步骤为:

  • 首先初始化两个数组,用来统计每个位置的其左边的1以及右边的0.
  • 两个循环就是用来统计每个位置0或者1出现的次数,用来翻转字符串。
  • 最终将所有统计的数组进行比较,选择最小的那个就是我们想要得到的结果。

三、代码:

function minFlipsMonoIncr(s: string): number {
    let res = Number.MAX_SAFE_INTEGER;
    let n = s.length;
    let leftArr = new Array(n).fill(0);
    let rightArr = new Array(n).fill(0);
    for(let i=0,one=0 ; i < n ; i++){
        leftArr[i] = one;
        if(s.charAt(i) === '1'){
            one++;
        }
    }
    for(let i=n-1,zero=0 ; i >= 0 ; i--){
        rightArr[i] = zero;
        if(s.charAt(i) === '0'){
            zero++;
        }
    }
    for(let i=0 ; i<n ; i++){
        res = Math.min(res,leftArr[i]+rightArr[i]);
    }
    return res;
};

四、总结:

这道题目使用了动态规划的思想,主旨就是统计出指定位置左边的1右边的0,因为我们想要将字符串变成单调递增的,所以我们需要将左边的1变成0,右边的0变成1,最终的结果就是每个位置两边翻转最小值。