题目:
如果一个二进制字符串,是以一些 0(可能没有 0)后面跟着一些 1(也可能没有 1)的形式组成的,那么该字符串是 单调递增 的。
给你一个二进制字符串 s,你可以将任何 0 翻转为 1 或者将 1 翻转为 0 。
返回使 s 单调递增的最小翻转次数。
解答:
方法一:根据当前字符串 结尾字符的值,进行分类讨论
class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n=len(s)
if n==1:
return 0
#dp[i][0]:将s[:i+1]调整为以'0'结尾的单调递增字符串所需的最小调整次数
#dp[i][1]:将s[:i+1]调整为以'1'结尾的单调递增字符串所需的最小调整次数
dp=[[0]*2 for _ in range(n)]
if s[0]=='0':
dp[0][1]=1
else:
dp[0][0]=1
for i in range(1,n):
if s[i]=='0':
dp[i][0]=dp[i-1][0]
dp[i][1]=min(dp[i-1][0],dp[i-1][1])+1
else:
dp[i][0]=dp[i-1][0]+1
dp[i][1]=min(dp[i-1][0],dp[i-1][1])
return min(dp[n-1])
方法二:直接讨论dp[0]和dp[1]
class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n=len(s)
if n==1:
return 0
dp=[[0]*2 for _ in range(n)]
if s[0]=='0':
dp[0][1]=1
else:
dp[0][0]=1
for i in range(1,n):
dp[i][0]=dp[i-1][0]+(0 if s[i]=='0' else 1)
dp[i][1]=min(dp[i-1][0],dp[i-1][1])+(0 if s[i]=='1' else 1)
return min(dp[n-1])
方法三:空间优化
class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n=len(s)
if n==1:
return 0
dp=[0]*2
if s[0]=='0':
dp[1]=1
else:
dp[0]=1
for i in range(1,n):
minv=min(dp[0],dp[1])
dp[0]=dp[0]+(0 if s[i]=='0' else 1)
dp[1]=minv+(0 if s[i]=='1' else 1)
return min(dp)