开启我的LeetCode刷题日记:926. 将字符串翻转到单调递增

61 阅读2分钟

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

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

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'

来源:力扣(LeetCode) 链接:leetcode.cn/problems/fl… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的思路

首选,明确一个思想,开头的0和结尾的1是没用的,先剪去

首选剪一次,如果剪没了,就是0次,本身就不需要操作

如果不是,判断0和1哪个多,1多就把0变1从后开始,0多就把开头的1变成0

不断执行,到字符串为空为止

代码实现

  function cut(s) {
        // 剪枝,剪去开头的0和结尾的1
        let c0 =0, c1 = 0;
        while (s.startsWith('0')) {
          s = s.slice(1);
          c0++;
        }
        while (s.endsWith('1')) {
          s = s.slice(0, s.length - 1);
          c1++;
        }
        return [c0, c1, s];
      }

      var minFlipsMonoIncr = function (s) {
        s = cut(s)[2];
        if (s.length === 0) {
          return 0;
        }
        // 初始化,统计0和1的个数
        let s0 = 0, s1 = 0;
        for (let i = 0; i < s.length; i++) {
          if (s[i] === '0') {
            s0++;
          } else {
            s1++;
          }
        }
        let r = 0;
        while (s.length) {
          // 0多,操作0
          if(s0 > s1){
            s = s.slice(1)
            s1--;
            r++;
          }else {
            s = s.slice(0, s.length - 1)
            r++;
            s0--;
          }
          let res = cut(s);
          s0 = s0 - res[0]
          s1 = s1 - res[1];
          s = res[2]
        }
        return r;
      };


总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹