算法--20181109--求01数组中连续的01长度相等的最长子数组索引

给定一个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

猜你喜欢

转载自blog.csdn.net/u014106644/article/details/83957335