遇到算法题先想出一种可行解,虽然不是最优,但是至少可以完成要求。优化什么的放到后面吧。
题目说明
题目出处:https://leetcode.com/problems/flip-string-to-monotone-increasing/
A string of '0’s and '1’s is monotone increasing if it consists of some number of '0’s (possibly 0), followed by some number of '1’s (also possibly 0.)
We are given a string S of '0’s and '1’s, and we may flip any ‘0’ to a ‘1’ or a ‘1’ to a ‘0’.
Return the minimum number of flips to make S monotone increasing.
Example 1:
Input: “00110”
Output: 1
Explanation: We flip the last digit to get 00111.
Example 2:
Input: “010110”
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.
Example 3:
Input: “010110”
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.
题目意思就是给定由 1 和 0 构成的字符串,通过修改其中的某些字符,可以使字符串是单调递增的,返回修改的最少次数。
初步的思路
要改变单个字符,使其单调递增,需要前面都是0,后面都是1即可满足;最极端的例子就是修改所有字符为 0 或 1,这是最简单的方法,但修改次数不一定是最少的。
我们以字符串中某单个字符为例子,如‘010101010’,加粗的第2个0为index,index前面1的个数one_num = 1,index后面0的个数zero_num = 3,所以修改的次数为 one_num + zero_num = 5, 也就是将index前面的字符都改为0, index后面的字符都改为1.
我们可以从左往右扫描一次字符串,找到修改次数的最小值, 即为所求。
计算优化
在上面的计算中,zero_num的计算是可以优化的
zero_num = index后面字符串的长度 - index后面1的个数
=(n - 1 - index) - (one - one_num)
其中n为字符串的长度,index为索引序号,one为字符串中1的个数,one_num 为inde之前字符串中1的个数
代码实现
class Solution(object):
def minFlipsMonoIncr(self, S):
"""
:type S: str
:rtype: int
"""
n = len(S)
one, one_num = S.count('1'), 0
res = min(n-one, one) #全部修改为1 或 全部修改为0
for index in range(n):
one_num += int(S[index])
zero_num = n - 1 - index - (one - one_num)
res = min(res, one_num + zero_num)
return res
空间复杂度为1,时间复杂度为O(N),还可以吧
更优的解法
待续。。。。