寻找数组中的最大值和最小值 (python)

本文介绍了四种不同的算法来寻找数组中的最大值和最小值,包括简单的线性遍历、分组比较、不交换数据的分组比较以及分治策略。这些算法在效率上有所不同,从需要比较2*N次到1.5*N次不等。对于扩展问题,还讨论了如何使用分治算法找到数组中的第二大数。
摘要由CSDN通过智能技术生成

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

解法 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值