二进制数组单次子数组翻转后最大0数量的Python完整实现
问题分析
要解决这个问题,我们需要找到执行最多一次子数组翻转(0和1互转)后,数组中0的最大数量。核心思路是将问题转化为寻找最大收益子数组:
- 原数组中0的总数是基础值。
- 翻转一个子数组时,子数组中的1会变成0(增加0的数量,收益+1),0会变成1(减少0的数量,收益-1)。我们需要找到能让收益最大化的子数组,从而得到翻转后0的最大数量。
解决方案代码
def max_zeros_after_flip(nums): if not nums: return 0 # 统计原数组中0的总数 count_0 = sum(1 for num in nums if num == 0) # 构建收益数组:1对应+1(翻转后增加1个0),0对应-1(翻转后减少1个0) gain = [1 if num == 1 else -1 for num in nums] # Kadane算法寻找最大子数组和(即最大收益) max_current = max_global = gain[0] for num in gain[1:]: max_current = max(num, max_current + num) if max_current > max_global: max_global = max_current # 允许不执行翻转的情况(取原0数量和翻转后的最大数量的较大值) # 若题目要求必须执行一次翻转,则直接返回 count_0 + max_global return max(count_0, count_0 + max_global)
关键逻辑说明
- 统计原0的数量:这是计算的基础值,后续翻转操作的收益都基于这个值增减。
- 收益数组转换:将原数组的1转为+1,0转为-1,子数组的和就代表翻转该子数组后0的数量变化量。
- Kadane算法求最大子数组和:该算法能高效找到连续子数组的最大和,对应翻转后能获得的最大收益。
- 结果计算:
- 如果最大收益为正,翻转对应子数组能增加0的数量,结果为原0数量加上最大收益。
- 如果最大收益为负,说明翻转任何子数组都会减少0的数量,此时选择不翻转,结果保持原0数量(符合用户提供的全0数组示例)。
- 若题目强制要求必须执行一次翻转,只需将返回值改为
count_0 + max_global即可,此时全0数组的结果为4。
测试用例验证
- 示例1:输入
[0,1,0,0,1,1,0]- 原0数量:4
- 收益数组:
[-1,1,-1,-1,1,1,-1] - 最大子数组和:2(对应翻转索引4-5的两个1)
- 结果:4+2=6,符合示例输出。
- 示例2:输入
[0,0,0,0,0]- 原0数量:5
- 收益数组:
[-1,-1,-1,-1,-1] - 最大子数组和:-1
- 结果:max(5,5-1)=5,符合示例输出。
- 边界用例:输入
[1,1,1]- 原0数量:0
- 收益数组:
[1,1,1] - 最大子数组和:3
- 结果:0+3=3(翻转整个数组为全0)。
- 边界用例:输入
[1]- 结果:1(翻转后变为0)。
内容的提问来源于stack exchange,提问作者Ayush Verma
相关产品推荐
相关产品推荐

