LeetCode连续数组 前缀和
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
示例 1:
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。
示例 2:
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
思路:
看到这一题,因为是连续子数组所以想尝试用滑动窗口来做,但仔细看题意给的条件好像又没法进行窗口收缩的判断,所以不能用滑动窗口。
这道题得用一个很巧妙的办法:将0变成-1,这样每对0和1的和其实就是-1+1=0,然后我们使用老生常谈的前缀和的方法:
1.当前缀和出现0时,就说明从这之前0和1的个数是相同的;
2.当相同的前缀和出现两次时,也说明这两次位置之间的范围中0和1个数是相同的。
代码具体实现时,我们用一个哈希表来存储非0前缀和以及它第一次出现的位置。具体细节直接看吧,写了很清楚的注释~~
代码:
class Solution(object):
def findMaxLength(self, nums):
#将原数组的0全部变为-1 则问题等价于“元素值总和为0的连续数组”
lenth = len(nums)
for i in range(lenth):
if nums[i]==0:nums[i]=-1#把0全都变成-1
qian = [0]*lenth#前缀和数组
qian[0]=nums[0]#初始化第一个
maxx=0
for i in range(1,lenth):#计算前缀和数组
qian[i]=qian[i-1]+nums[i]#逐个累加即可
hashmap={}#存储非0前缀和的哈希表
for i in range(lenth):
#对前缀和的判断有两种 一种是前缀和为0,这最直接,则说明这往前和为0
if qian[i]==0:maxx = max(maxx,i+1)
#第二种就是出现两次或以上的前缀和,他们之间的和为0
if qian[i] not in hashmap:#如果第一次出现,则放入哈希表
hashmap[qian[i]]=i#key是前缀和的值,value是它的位置
else:#如果不是第一次出现,则取第一次出现的位置做距离计算,并尝试更新最大值
maxx = max(maxx,i-hashmap[qian[i]])
return maxx
如果提交运行后会发现,这其实是一个效率不太高的写法,因为前缀和可以直接压缩到常数级别而并不一定要用数组。不过这样写思路最清晰也最方便理解,我还是喜欢这种方式~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了