获得第k小数-二分法的巧妙应用

寻找第k小数
已知:双数组已排序,求所有元素中第k小(大)的数
该题解法有多种:
1.暴力解法,对所有元素排序,取出第k小数;
2.双指针,从各数组首位开始比较,更小的删除,遍历直到删除k-1个元素,则此时指针指的元素中更小值满足条件;
3.时间复杂度o(log(m+n)),容易想到二分法,结合双指针做法,即每次删除k//2个元素,以下详细说明
在这里插入图片描述

#第k小数通用
def getkminnumber(n1:List[int],n2:List[int],k):
            #定义更长数列在前
            #每一步去除n/2个数
            if len(n1) <= len(n2):
                n1,n2=n2,n1
            if len(n2)==0:
                return n1[k-1]
            if k == 1:
                return min(n1[0],n2[0])
            t=min(k//2-1,len(n2)-1)
            q=k//2-1+k//2-1-t
            if n1[q]<n2[t]:
                n1=n1[q+1::]
                k=k-q-1
            else:
                n2 = n2[t+1::]
                k=k-t-1
            

            return getkminnumber(n1,n2,k)
#第k大数,需要注意倒序排列与顺序排列的区别(顺序从0到len-1,倒序从-len到-1)
def getkmaxnumber(n1:List[int],n2:List[int],k):
            #定义更长数列在前
            if len(n1) <= len(n2):
                n1,n2=n2,n1
            if len(n2)==0:
                return n1[-k]
            if k == 1:
                return max(n1[-1],n2[-1])
            t=min(k//2,len(n2))
            q=k//2+k//2-t
            if n1[-q]<n2[-t]:
                n2=n2[:-t]
                k=k-t
            else:
                n1 = n1[:-q]
                k=k-q
            

            return getkmaxnumber(n1,n2,k)
#调用
m=len(nums1)
        n=len(nums2)
        left = getkminnumber(nums1,nums2,(m+n+1)//2)
        #print(left)
        right=getkmaxnumber(nums1,nums2,(m+n+1)//2)
        #print(right)
        return (left+right)/2
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值