数组是最简单的一种数据结构,我们经常碰到的一个基本问题,就是寻找整个数组中的最大的数,或者最小的数。这时,我们都会扫描一遍数组,把最大(最小)的数找出来。如果我们需要同时找到最大和最小的数呢?

解法 1

先扫描一遍数组,找到最大的数以及最小的数。这样我们需要比较2*N次才能求解。

nums = list(map(int, input().split()))
Maxnums , Minnums = nums[0], nums[0]

for i in range(len(nums)):
    if nums[i] > Maxnums:
        Maxnums = nums[i]
    if nums[i] < Minnums:
        Minnums = nums[i]
print(Minnums,Maxnums)

解法 2

一般情况下,最大的数和最小的数不会是同一个数(除非N=1)。这样可以把数组分为两组(这是概念上的分组奇数位为一组,偶数位为一组),然后在这两部分分别找到最大和最小的数。

经过N/2次比较后,较大的数都放在了偶数位,较小的数放在了奇数位。最后在奇数位和偶数位分别·求出最小值和最大值个需要比较N/2次,整个算法需要比较1.5N次。

nums = list(map(int,input().split()))
N = len(nums) if len(nums)%2 == 0 else len(nums)-1
for i in range(0,N,2):
    if nums[i] < nums[i+1]:
        nums[i], nums[i+1] = nums[i+1], nums[i]
maxnums, minnums = nums[i], nums[i+1]
for i in range(0,N,2):
    if nums[i] > maxnums:
        maxnums = nums[i]
    if nums[i+1] < minnums:
        minnums = nums[i+1]
maxnums = maxnums if nums[-1]<maxnums else nums[-1]
minnums = minnums if nums[-1]> minnums else nums[-1]
print(maxnums,minnums)

解法 3

将数组分为两组但不交换数据,同一组的两个数比较后,不再调整顺序,而是将其中较小的数与当前Min作比较,如果该数小于当前Min则更新Min。同理,将其中较大的数与当前的Max作比较,如果当前数大于当前Max,则更新Max。需要比较的次数为1.5N。

nums = list(map(int,input().split()))
Max, Min = nums[0], nums[0]
N = len(nums) if len(nums)%2 == 0 else len(nums)-1
for i in range(0,N,2):
    if nums[i] > nums[i+1]:
        if Max < nums[i]:
            Max = nums[i]
        if Min > nums[i+1]:
            Min = nums[i+1]
    else:
        if Max < nums[i+1]:
            Max = nums[i+1]
        if Min > nums[i]:
            Min = nums[i]
Max = Max if nums[-1]<Max else nums[-1]
Min = Min if nums[-1]> Min else nums[-1]
print(Max,Min)

解法 4

使用分治算法求解N个数中的最小值和最大值。需要比较的次数为1.5N-2。

def search(nums, L, R): # 返回Max,Min
    if R - L <= 1:
        if nums[L] < nums[R]:
            return [nums[R], nums[L]]
        else:
            return [nums[L], nums[R]]
    maxL, minL = search(nums, L, L + (R-L)//2)
    maxR, minR = search(nums, L + (R-L)//2 + 1, R)
    maxV, minV = -2**31-1, 2**31
    if maxL > maxR:
        maxV = maxL
    else:
        maxV = maxR
    if minL < minR:
        minV = minL
    else:
        minV = minR
    return [maxV, minV]

nums = list(map(int, input().split()))
Max, Min = search(nums, 0, len(nums)-1)
print(Max, Min)

扩展

使用分治算法寻找N个数组中的第二大数。

def search(nums, L, R): # 返回Max1,Max2
    if R == L:
        return [nums[R],-2**23]
    elif R-L == 1:
        if nums[L] < nums[R]:
            return [nums[R], nums[L]]
        else:
            return [nums[L], nums[R]]
    Lmax1, Lmax2 = search(nums, L, L + (R-L)//2)
    Rmax1, Rmax2 = search(nums, L + (R-L)//2 + 1, R)
    if Lmax1 > Rmax1:
        return [Lmax1, max(Lmax2,Rmax1)]
    else:
        return [Rmax1, max(Rmax2,Lmax1)]

nums = list(map(int, input().split()))
Max1, Max2 = search(nums, 0, len(nums)-1)
print(Max1, Max2)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐