1529-最少的后缀翻转次数
给你一个长度为 n
、下标从 0 开始的二进制字符串 target
。你自己有另一个长度为 n
的二进制字符串 s
,最初每一位上都是 0 。你想要让 s
和 target
相等。
在一步操作,你可以选择下标 i
(0 <= i < n
)并翻转在 闭区间 [i, n - 1]
内的所有位。翻转意味着 '0'
变为'1'
,而 '1'
变为 '0'
。
返回使 __s
__ 与 __target
相等需要的最少翻转次数。
示例 1:
**输入:** target = "10111"
**输出:** 3
**解释:** 最初,s = "00000" 。
选择下标 i = 2: "00 _ **000**_ " -> "00 _ **111**_ "
选择下标 i = 0: " _ **00111**_ " -> " _ **11000**_ "
选择下标 i = 1: "1 _ **1000**_ " -> "1 _ **0111**_ "
要达成目标,需要至少 3 次翻转。
示例 2:
**输入:** target = "101"
**输出:** 3
**解释:** 最初,s = "000" 。
选择下标 i = 0: " _ **000**_ " -> " _ **111**_ "
选择下标 i = 1: "1 _ **11**_ " -> "1 _ **00**_ "
选择下标 i = 2: "10 _ **0**_ " -> "10 _ **1**_ "
要达成目标,需要至少 3 次翻转。
示例 3:
**输入:** target = "00000"
**输出:** 0
**解释:** 由于 s 已经等于目标,所以不需要任何操作
提示:
n == target.length
1 <= n <= 105
target[i]
为'0'
或'1'
方法一:贪心
根据翻转操作的定义,选定下标 i 之后,翻转从下标 i 到下标 n-1 的每个字符,在下标 i 前面的字符则不被翻转。因此,如果一个字符被翻转,则一定是选择了该字符的下标或者该字符前面的某个下标,然后进行了翻转操作。
初始时,所有的字符都是 0。对于下标为 0 的字符,如果其在 target 中的值是 1,则一定有一次对下标为 0 的字符的翻转操作。
对于下标为 i(i>0)的字符,如果其在 target 中的值与前一个字符(即下标为 i-1 的字符)的值不同,则一定有一次对下标为 i 的字符的翻转操作。
由此可以想到一个贪心的思路:从前往后遍历 target,对每个下标判断是否进行了翻转操作即可,同时计算最少翻转次数。
1 | class Solution { |
1 | public class Solution { |
1 | class Solution { |
1 | class Solution: |
复杂度分析
时间复杂度:O(n),其中 n 是字符串 target 的长度。遍历字符串一次。
空间复杂度:O(1)。只需要维护常量的额外空间。
Comments