给定一个01数组,例如0100001000011111000011100001010010010100 求该数组中01数字个数相等的最长连续子数组的索引。
解法1:常规解法遍历所有可能,统计连续子数组中0,1个数相等的最长子数组。 时间复杂度为O(N3)
def maxSubArray(num):
max = 0
lo = 0
hi = 0
#range(a,b) =[a,b)
for i in range(len(num)):
for j in range(i+1, len(num)):
#print (i,j)
c0 = 0
c1 = 0
for k in range(i, j+1):
#print ('k',k)
if num[k]==0:
c0 = c0 + 1
else:
c1 = c1 + 1
if c0==c1 and c0+c1>max:
lo = i
hi = j
max = c0+c1
return lo, hi
解法2:时间复杂度O(N2) 子数组求和如果和等于长度一半说明该子数组0,1个数相等
利用子数组和与长度关系可以将时间复杂度降为O(N2)
def maxSubArray2(num):
max = 0
lo = 0
hi = 0
#range(a,b) =[a,b)
for i in range(len(num)):
sum = num[i]
for j in range(i+1, len(num)):
sum = sum + num[j]
if sum*2==j-i+1 and sum*2>max:
lo = i
hi = j
max = sum*2
return lo, hi
解法3:时间复杂度O(N) 空间复杂度O(N)
利用数组B[i] 表示数组num从0--i中0,1个数之差
当B[i]==0时 说明0---i符合条件 长度=i+1
当B[i]==B[j]时,说明 i+1----j符合条件,个数之差=0,长度为j-(i+1)+1 = j-i
利用一个dict存放 B[i]以及与num索引的关系 当B[i]存在于dict中,说明有符合条件的子数组,更新最大长度即可,否则将B[i]:i存放于dict中
def maxSubArray3(num):
B = [0]*len(num)
count=[0,0]
dict = {}
max = 0
lo = 0
hi = 0
for i in range(len(num)):
count[num[i]] += 1
B[i] = count[0] - count[1]
if B[i]==0 and i+1>max:
hi = i
max = i+1
continue
if B[i] in dict.keys():
if i-dict[B[i]]>max:
lo = dict[B[i]]+1
hi = i
max = i-dict[B[i]]
else:
dict[B[i]] = i
#print (B)
#print (dict)
return lo, hi
输入数组:
num = [0,1,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,1]
B[i]数组变化情况:
dict变化情况:
最终结果为num[5,14] 即最大长度为10