陣列-BAT面試經典試題:絕對眾數,零子陣列,最大子陣列和
1.絕對眾數問題
定義:給定N個數,稱出現次數最多的數為眾數:若某眾數出現的次數大於N/2,稱該眾數為絕對眾數。
如:A={1,2,1,3,2}中,1和2都是眾數,但都不是絕對眾數;A={1,2,1,3,1}中,1是絕對眾數。
已知給定的N個整數存在絕對眾數,以最低的時空負責度計算該絕對眾數。
演算法分析:
刪除陣列A中的兩個不同的數,絕對眾數不變:若兩個數有一個是絕對眾數,則剩餘的N-2個數中,絕對眾數仍大於(N-2)/2;若兩個數中沒有絕對眾數,則不影響絕對眾數
演算法描述:
記m為候選絕對眾數,出現的次數為c,初始化為0.
遍歷陣列A:
若C==0,則m=A[i];
若c0且mA[i],則同時刪掉m和A[i];
若c0且m==A[i],則c++;
python實現:
def Mode(arr): count=0 m=arr[0] for i in range(len(arr)): if count==0: m=arr[i] count=1 elif m!=arr[i]: count-=1 else: count+=1 return m if __name__ =='__main__': arr=[8,8,6,1,6,8,1,1,1,1,1] print(Mode(arr))
2.零子陣列
求對於長度為N的陣列A,求連續子陣列的和最接近0的值,及對應的子陣列。如陣列A=[1,-2,3,10,-4,7,2,-5].
演算法思路:
1)計算前 i 個元素的和,新的陣列記為sum;
2) 對陣列sum排序;
3)計算排序後sum陣列相鄰兩個元素的差,差最接近零的即為本題所求1。
如果要求返回對應的子陣列:記差最接近為0的兩個元素值分別為 m 和 n,找到 m 和 n 第1)步中sum陣列對應的索引位置,i 和 j ,i 和 j 之間的元素即為所求子陣列。
python實現:
def MinSubarray(A): sum_1=[] for i in range(len(A)+1): sum_1.append(sum(A[:i])) sum_=sorted(sum_1) difference=abs(sum_[1]-sum_[0]) m,n=sum_[1],sum_[0] result=difference for i in range(len(sum_)-1): difference=abs(sum_[i+1]-sum_[i]) if result>difference: result=difference m,n=sum_[i+1],sum_[i] idx_1=sum_1.index(m) idx_2=sum_1[idx_1+1:].index(n)+idx_1+1 subarr=A[idx_1:idx_2] return result,subarr if __name__ =='__main__': A=[1,-2,3,10,-4,7,2,-5] value,subarr=MinSubarray(A) print(value) print(subarr)
3. 最大子陣列
給定一個數組A[0,1,...n-1],求A的連續子陣列,使得該子陣列的和最大。例如陣列A=[1,-2,3,10,-4,7,2,-5].
演算法分析:
第一種方法,返回最大子陣列和的值:
記S[i]為以A[i]結尾的陣列中和最大的子陣列,則S[i+1]=max(S[i]+A[i+1],A[i+1]),S[0]=A[0],遍歷 i 。動態規劃:最優子問題,時間複雜度O(n)。
第二種方法,返回最大子陣列和的值和子陣列。
計算以A[i]結尾的元素的和,記錄A[i]前面和最小的位置與當前 i 之間的子陣列。從1到N遍歷,即可得所求。
def MaxSubarray(A):
sum1=A[0]
result=sum1
subarr=[]
subarr.append(A[0])
for i in range(1,len(A)):
if sum1>0:
sum1+=A[i]
subarr.append(A[i])
else:
sum1=A[i]
result=max(sum1,result)
return result
def MaxSubarray1(A):
begin=end=0
Sum=A[0]
result=Sum
for i in range(1,len(A)):
if Sum>0:
Sum+=A[i]
else:
Sum=A[i]
fromNew=i
if result<Sum:
result=Sum
begin=fromNew
end=i
return result,A[begin:end]
if __name__ =='__main__':
A=[1,-2,3,10,-4,7,2,-5]
print('First method:')
print(MaxSubarray(A))
value,arr=MaxSubarray1(A)
print('Second Method:')
print(value)
print(arr)
未完待續……
說明:本部落格的題目和演算法思路來自小象學院BAT演算法特訓班網路課。