数组-BAT面试经典试题:绝对众数,零子数组,最大子数组和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010420283/article/details/82939844

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];

若c\neq0且m\neqA[i],则同时删掉m和A[i];

若c\neq0且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算法特训班网络课

猜你喜欢

转载自blog.csdn.net/u010420283/article/details/82939844