求两个有序列表的中值

这篇博客探讨了如何找到两个有序列表的中位数。通过分析i和j的索引,确定中位数的位置。对于奇数个元素的情况,中位数是第(m+n)/2个元素;偶数个元素时,需要结合(i, j)及其附近的值来确定。博主提供了主要的程序框架,包括主循环中i和j的移动策略,以及不同情况下的边界处理。当m+n为奇数时,i, j对应最小值即为中位数;偶数时,需结合i, j附近值计算中位数。" 95729858,8682508,方向导数的定义与性质,"['数学', '微积分', '多元函数']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

先放张图看一下:

i,j对应的list的值大于list前面的数(程序主循环移动i,j时候考虑的便是小的数,索引后移),有i+j个数。(i,j分别为num1和num2的索引)

若为奇数:中位数为第\frac{m+n+1}{2}

若为偶数:中位数为第\frac{m+n+1}{2}(整除)位和第\frac{m+n+1}{2}+1(整除)

所以目标明确为使得i+j=\frac{m+n+1}{2}-1=\frac{m+n-1}{2},则仅i,j及其左右处的值与所求中位数相关。

以下为主要的程序框架及代码:

1、主循环中进行i,j的移动:注意当i或j移动到顶端时单独考虑:

情况有三种:(以i到达顶端为例)直接将j移动到指定位置即j += mid-k,之后考虑以下三种情况:

       1)nums2[j-1]>nums1[i](nums1顶端值比较小)

       2)j+1<len(nums2) and nums2[j+1]<nums1[i](nums1顶端处值比较大)

       3)其它

2、若i,j正确退出主循环

若m+n为奇数,则i,j对应最小值为所求中值;

若m+n为偶数,需要考虑i,j中对应的最小值与i,j附近的值均值得到中位数,并且i,j总有一个位于数组中间;以j位于中间为例进行解释:

分成以下三种情况:

1)nums1[i] > nums2[j+1](i处的值大于j+1处值)

2)i+1<len(nums1) and nums1[i+1]<nums2[j](j处的值大于i+1处值)

3)其它

 3、python代码

    def findMedianSortedArrays(self, nums1: list, nums2: list) -> float:
        if len(nums1)==0 or len(nums2)==0:
            if len(nums1)>0:
                return nums1[(len(nums1)+1)//2-1] if len(nums1)%2==1 else (nums1[(len(nums1)+1)//2-1]+nums1[(len(nums1)+1)//2])/2
            else:
                return nums2[(len(nums2) + 1) // 2 - 1] if len(nums2) % 2 == 1 else (nums2[(len(nums2) + 1) // 2 - 1] +nums2[(len(nums2) + 1) // 2]) / 2
        mid = (len(nums1) + len(nums2)-1) // 2
        i = 0
        j = 0
        for k in range(mid):
            if i == len(nums1) - 1:
                j += mid-k
                if(nums2[j-1]>nums1[i]):
                    return nums2[j-1] if (len(nums1) + len(nums2)) % 2 == 1 else (nums2[j-1] + nums2[j]) / 2
                elif(j+1<len(nums2) and nums2[j+1]<nums1[i]):
                    return nums2[j] if (len(nums1) + len(nums2)) % 2 == 1 else (nums2[j] + nums2[j+1]) / 2
                else:
                    return min(nums1[i],nums2[j]) if (len(nums1) + len(nums2)) % 2 == 1 else (nums1[i] + nums2[j]) / 2
            elif j == len(nums2) - 1:
                i += mid-k
                if (nums1[i- 1] > nums2[j]):
                    return nums1[i - 1] if (len(nums1) + len(nums2)) % 2 == 1 else (nums1[i - 1] + nums1[i]) / 2
                elif(i+1<len(nums1) and nums1[i+1]<nums2[j]):
                    return nums1[i] if (len(nums1) + len(nums2)) % 2 == 1 else (nums1[i] + nums1[i+1]) / 2
                else:
                    return min(nums1[i], nums2[j]) if (len(nums1) + len(nums2)) % 2 == 1 else (nums1[i] + nums2[j]) / 2
            else:
                if (nums1[i] < nums2[j]):
                    i += 1
                else:
                    j += 1
        if (len(nums1) + len(nums2)) % 2 == 1:
            if(nums1[i]<nums2[j]):
                return nums1[i]
            else:
                return nums2[j]
        else:
            if(j!=len(nums2)-1):
                if(nums1[i] > nums2[j+1]):
                    return (nums2[j]+nums2[j+1])/2
                elif(i+1<len(nums1) and nums1[i+1]<nums2[j]):
                    return (nums1[i] + nums1[i + 1]) / 2
                else:
                    return (nums2[j] + nums1[i]) / 2
            if(i!=len(nums1)-1):
                if (nums2[j] > nums1[i + 1]):
                    return (nums1[i] + nums1[i + 1]) / 2
                elif(j+1<len(nums2)and nums2[j+1]<nums1[i]):
                    return (nums2[j]+nums2[j+1])/2
                else:
                    return (nums1[i] + nums2[j]) / 2
            return  (nums1[i] + nums2[j]) / 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值