持续创作,加速成长!这是我参与「掘金日新计划 · 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 <= 105s[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,最终的结果就是每个位置两边翻转最小值。