【刷题日记】926. 将字符串翻转到单调递增

简介: 本次刷题日记的第 61 篇,力扣题为:926. 将字符串翻转到单调递增,中等

本次刷题日记的第 61 篇,力扣题为:926. 将字符串翻转到单调递增中等

一、题目描述:

image.png

继续做一些字符串的题,本次还是带有函数特性的单调递增翻转字符串


二、这道题考察了什么思想?你的思路是什么?

翻转字符串成单点递增的,看看都展示了哪些重要信息:

  • 题目中给出的一个字符串,里面的字符只有 01且顺序不定,也不会有其他多余的字符种类
  • 题目要求我们编写程序将字符串中的 0 翻转成 1 ,或者是将 1 翻转成 0 ,只要能够达到最终的字符串是单调递增的题目不需要咱们真的在原字符串上进行翻转,只需要返回需要翻转的次数即可,且还需要明确达到目的的翻转次数要是最小的
  • 什么是单调递增,如果这个字符串最终结果是 全 0 或者 全 1 ,那么算是单点递增的,另外如果 01 都在同一个字符串中的情况下,一定是 0 开头, 1 结尾,且相邻字符是一样的,除了字符串中间的 0 过渡到 1 的时候

分析

那么我们看了上述重要信息,知道单调递增是怎回事之后,我们是需要来考虑如何翻转的事情了

其实将原字符串翻转成单调递增的字符串不麻烦,很轻易就能够想到,直接将字符串中的 0 全部翻转成全 1 ,或者全 1 翻转成 0得到的结果一定是单调递增的

可是,题目还有一个要求是,我们得到的结果翻转次数要是最小的才可以

那么接下来,咱么你要考虑的是,如何有想法的翻转,而不是无脑的翻转

翻转无非两种,即,0 翻转成 1 ,或者将 1 翻转成 0

那我们如何判断要进行哪一种翻转呢?


思考片刻,我们知道当前位置的字符,是否需要翻转成 0 / 1 是依赖于当前字符的前一个字符翻转成啥来决定的,例如

  • 如果字符串就是一个 "0" ,咱们可以定义 2 个变量来记录当前字符需要翻转成0 / 1 的次数
0

例如上述字符串,dp[0][0] = 0 , dp[0][1] = 1 ,什么意思呢?

也就是说上述的第 0 个字符,将他翻转成 0 ,需要翻转 0 次,将他翻转成 1 需要翻转 1 次

又如:

1

则,就有 dp[0][0] = 1 , dp[0][1] = 0

再如:

0 1

同样的逻辑和方法,就有

dp[0][0] = 0 , dp[0][1] = 1

dp[1][0] = dp[0][0] = 0, dp[1][1] =0 + min(dp[0][0], dp[0][1]) = 0

啥意思呢?

对于需要翻转成字符0 如果是需要是单调递增的话,那么他的前面必须是 0 ,因此需要直接将前面的字符明确需要翻转成 0 的次数 直接赋值即可

那么对于需要翻转成字符1 需要是单调递增的话,他的前面可以是 0 ,也可以是 1 ,所以其实直接将前面字符串明确翻转成 0 的次数,或者是 1 的次数直接加上即可,但是题目要求我们是翻转最小的次数,因此需要求前面翻转次数的最小值

看到这里,相信思路应该会很清晰了吧,自己可以推演一下就能更加深刻了,这个其实就是使用了动态规划的方法

需要整体字符串满足单调递增,那么局部也需要是满足单调递增的,直到将字符串 s 完全遍历,得到的结果,咱们去 翻转成 0 的次数 与 翻转成 1 的次数的最小值即可

三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码

编码的时候,咱们初始化可以将 dp0 , 和 dp1 都赋值为 0,表示至少翻转 0 次

编码如下:

func minFlipsMonoIncr(s string) int {
    dp0, dp1 := 0, 0
    for _, v := range s {
        tmp0, tmp1 := dp0, min(dp0, dp1)
        if v == '1'{
            tmp0++
        }else{
            tmp1++
        }
        dp0, dp1 = tmp0, tmp1
    }
    return min(dp0, dp1)
}
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

四、总结:

image.png

就目前这种实现方式来看,时间复杂度是非常明确的,咱们遍历了一遍 s 字符串,因此时间复杂度是 O(n)

空间复杂度是 O(1) , 又因为咱们引入的变量都是常数级别的空间消耗

原题地址:926. 将字符串翻转到单调递增

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~


相关文章
|
程序员
【Leetcode】面试题 01.02. 判定是否互为字符重排、面试题 01.04. 回文排列
目录 面试题 01.02. 判定是否互为字符重排 面试题 01.04. 回文排列
66 0
|
2月前
|
算法
AcWing 1360. 有序分数(每日一题)
AcWing 1360. 有序分数(每日一题)
|
7月前
|
监控
代码随想录Day31 贪心06 T738 单调递增的数字 T968监控二叉树
代码随想录Day31 贪心06 T738 单调递增的数字 T968监控二叉树
52 0
|
存储 算法 Serverless
代码随想录算法训练营第六天 | LeetCode 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
代码随想录算法训练营第六天 | LeetCode 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
74 0
代码随想录算法训练营第六天 | LeetCode 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
|
监控 算法 程序员
代码随想录算法训练营第三十六天 | LeetCode 738. 单调递增的数字、贪心算法总结
代码随想录算法训练营第三十六天 | LeetCode 738. 单调递增的数字、贪心算法总结
45 0
|
算法 安全
代码随想录算法训练营第六天| 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和
代码随想录算法训练营第六天| 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和
|
机器学习/深度学习 监控 算法
代码随想录训练营day36| 738.单调递增的数字 968.监控二叉树
代码随想录训练营day36| 738.单调递增的数字 968.监控二叉树
125 1
|
机器学习/深度学习 监控 算法
代码随想录训练营day37| 738.单调递增的数字 968.监控二叉树
代码随想录训练营day37| 738.单调递增的数字 968.监控二叉树
|
搜索推荐 Cloud Native
【刷题日记】1403. 非递增顺序的最小子序列
【刷题日记】1403. 非递增顺序的最小子序列
|
算法 C++ Python
每日算法系列【LeetCode 926】将字符串翻转到单调递增
每日算法系列【LeetCode 926】将字符串翻转到单调递增