【LeetCode】926. 将字符串翻转到单调递增

1,223 阅读3分钟

image.png

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

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

image.png

  • 题目示例

image.png

  • 题目解析

    • 1 <= s.length <= 10**5
    • s[i] 为 '0' 或 '1'

二、思路分析:

我们读取题目,题目要求对一个二进制的字符进行翻转,使其里面字符呈单调递增。返回最小的翻转次数。

在题目中,我们可以获取到如下几点信息💻:

  • 字符串s都是由 "0" 和 "1"组成
  • 单调递增规则:不能出现'0'和"1"交错的现象,因此只能有三种形式出现000..111,000...000,111..111
  • 通过翻转,使"0"变成"1",或者使"1"变成"0",来达到字符串s单调递增

我们来通过如下示列2来,推理说明如下:

image.png

还记得,我们刷过的497. 非重叠矩形中的随机点题目,通过前缀和记录所有的矩形的面积。

因此,今天本题仍然使用此思路,使用前缀和来记录📝,遍历字符串前面出现的字符'0'或者"1"的个数,解答该题的思路:

  • 方法一:前缀和+枚举

    • 首先,通过前缀和方法计算出字符串出现字符‘1’翻转个数
    • 前缀和公式:P[i+1] = p[0]+p[1]+p[2]+...+p[i]
    • 当p[i]为x个1,则需要翻转的次数为len(s)-i-(p[len(s)]-p[i])个字符'0'需要去翻转
    • 直到遍历完字符串s所有字符,返回最小值
    • 我们定义初始结果ans时,要定义大于10**5,否则会通过不了81/93条case
    class Solution(object):
        def minFlipsMonoIncr(self, s):
            """
            :type s: str
            :rtype: int
            """
            p = [0]*(len(s)+1)
            for i in range(len(s)):
                p[i+1] = p[i] + int(s[i])
    
            ans = 1000000
            for i in range(len(s)+1):
    
                ans = min(ans,p[i]+len(s)-i-(p[len(s)]-p[i]))
    
            return ans
    
  • 方法二:简单的动态规划

    • 本题中,对于字符串s来说,只存在要么翻转字符'0'或者字符'1'两种可能
    • 因此,我们只需要定义两个变量来dp0来记录翻转0次数,dp1来记录翻转1的次数
    • 字符1和字符0翻转中,只存在四种情况 00,11,10,01,因此dp[i]只与dp[i-1]有关
    class Solution(object):
        def minFlipsMonoIncr(self, s):
            """
            :type s: str
            :rtype: int
            """
            dp0 = dp1 = 0
    
            for i in s:
                tmpdp0,tmpdp1 = dp0,min(dp0,dp1)
                if i == "1":
                    tmpdp0 = tmpdp0 +1
                else:
                    tmpdp1 = tmpdp1 + 1
    
                dp0,dp1 = tmpdp0,tmpdp1
    
            return min(dp0,dp1)
    

三、总结:

本题,仍然考察我们前缀和使用方法,通过前缀和记录字符串左边出现1到个数,然后通过公式计算出n-i-(p[n]-p[i])个0的需要翻转的,最后遍历完整个字符串s返回最小值。同样也可以使用动态规划,因为dp[i]与dp[i-1]存在关系,只有存储下一个状态值,减少空间的浪费,AC提交记录如下: image.png

  • 时间复杂度O(n),n为字符串s的长度
  • 空间复杂度O(1),无额外空间占用

以上是本期内容,欢迎大佬们点赞评论,下期见~~