1529. 最少的后缀翻转次数

目录

【算法题】最少翻转次数使字符串相等 — 翻转后缀二进制字符串问题解析

题目描述

题目分析

解题方法

复杂度分析

代码实现(Python)

示例说明

示例 1:

总结与思考


【算法题】最少翻转次数使字符串相等 — 翻转后缀二进制字符串问题解析

题目描述

给定一个长度为 n 的二进制字符串 target,下标从 0 开始。你拥有另一个长度为 n 的二进制字符串 s,最初 s 的每一位都是 0

你的目标是通过若干次操作,使得字符串 s 变得和 target 一样。

操作规则

  • 你可以选择一个下标 i0 <= i < n),翻转从位置 i 到位置 n-1 之间的所有位。
  • 翻转的定义是:0 变为 11 变为 0

问:为了使 starget 相等,最少需要多少次翻转操作?


题目分析

这道题的关键是理解翻转操作对字符串状态的影响:

  • 一次操作会影响从某个位置 i 到字符串末尾所有的位。
  • 操作次数和位置选择都会影响最终的字符串状态。

如果按字面意思模拟翻转操作,会很耗时,因为每次翻转需要操作后缀的所有位。对于大数据,这种模拟不可行。

因此,我们需要一个简洁的策略:

  • 观察从左到右,字符串 s 从全 0 开始。
  • 翻转会改变当前位置及其后的所有位。
  • 只要当前位置和目标字符串不同,就需要翻转一次。

这启发我们采用贪心算法,沿着字符串从左到右处理:

  • 维护一个变量记录当前 s 的实际状态。
  • 遍历 target
    • 如果当前位置 target[i] 和当前状态不一致,说明必须翻转后缀。
    • 翻转次数加一,同时更新当前状态为目标字符。

解题方法

  1. 初始化
    • flips = 0,表示操作次数。
    • cur = '0',表示当前字符串 s 的实际状态(初始全0)。
  1. 遍历字符串 target
    • 对每个字符 ch
      • ch != cur,说明当前位置的 s 需要翻转才能与 target 对应。
        • flips += 1,记录一次操作。
        • cur = ch,更新当前状态,表示经过翻转后,从当前位置开始的状态变为 ch
  1. 返回 flips 即为答案

复杂度分析

  • 时间复杂度:O(n),只需一次遍历字符串。
  • 空间复杂度:O(1),只使用常数个变量。

相比模拟翻转字符串,每次操作需要翻转子串,效率更高。


代码实现(Python)

class Solution:
    def minFlips(self, target: str) -> int:
        flips = 0
        cur = '0'  # 当前实际状态
        for ch in target:
            if ch != cur:
                flips += 1
                cur = ch  # 状态切换
        return flips

示例说明

示例 1:

target = "10111"
初始 s = "00000"

遍历过程:

i

target[i]

cur

不同?

flips

说明

0

'1'

'0'

1

翻转后缀 [0..4],s变为11111

1

'0'

'1'

2

翻转后缀 [1..4],s变为10000

2

'1'

'0'

3

翻转后缀 [2..4],s变为10111

3

'1'

'1'

3

无需翻转

4

'1'

'1'

3

无需翻转

最终翻转次数:3


总结与思考

  • 本题关键是避免直接模拟翻转,通过维护一个“当前状态”变量,贪心地翻转位置,使时间复杂度降为线性。
  • 这种“状态切换”的思路在类似“区间翻转”、“位反转”问题中也很常见。
  • 通过分析状态变化,可以有效推导最优解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值