1. 程式人生 > >演算法--20181109--求01陣列中連續的01長度相等的最長子陣列索引

演算法--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