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算法特训班网络课。