LeetCode-4-Median-of-Two-Sorted-Arrays 递归求两有序数组第k小

本文介绍了一种使用递归方式找到两个有序数组合并后的中位数的方法,并提供了C++, Java及Python三种语言的实现。该算法的时间复杂度为O(log(min(m,n))),其中m和n分别为两个数组的长度。

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

这个题给了俩有序数组,要求合并后的中位数,要求用lg(m+n)的算法,明显是要二分了,但是正着写太麻烦了,还要考虑奇偶,于是我参考了一下网上大多数人的做法,用递归的方式求。

我用C++写完交了后告诉我才击败了6%的选手,我不服,然后把所有的nums1.size()这种的东西都用常量存起来,然后再交就能打败50%的人了,访问vetcor的size还是很耗费时间的。

C++

86ms

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int totalLen=nums1.size()+nums2.size();
        if(totalLen&1){
            return findKthMin(nums1,0,nums2,0,totalLen/2+1);
        }
        else return (findKthMin(nums1,0,nums2,0,totalLen/2+1)+findKthMin(nums1,0,nums2,0,totalLen/2))*1.0/2;
    }
    
    double findKthMin(vector<int>& numsA,int startA,vector<int>& numsB,int startB,int k){
        if(numsA.size()-startA<numsB.size()-startB){
            return findKthMin(numsB,startB,numsA,startA,k);
        }
        if(numsB.size()-startB==0){
            return numsA[startA+k-1];
        }
        if(k==1){
            return min(numsA[startA],numsB[startB]);
        }
        int cutB=min(k/2,(int)(numsB.size()-startB));
        int cutA=k-cutB;
        if(numsA[startA+cutA-1]<numsB[startB+cutB-1]){
            return findKthMin(numsA,startA+cutA,numsB,startB,k-cutA);
        }
        else if(numsA[startA+cutA-1]>numsB[startB+cutB-1]){
            return findKthMin(numsA,startA,numsB,startB+cutB,k-cutB);
        }
        else{
            return numsA[startA+cutA-1];
        }
    }
    
};

C++

59ms

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        
        int len1=nums1.size();
        int len2=nums2.size();
        int totalLen=len1+len2;
        if(totalLen&1){
            return findKthMin(nums1,0,nums2,0,totalLen/2+1,len1,len2);
        }
        else return (findKthMin(nums1,0,nums2,0,totalLen/2+1,len1,len2)+findKthMin(nums1,0,nums2,0,totalLen/2,len1,len2))*1.0/2;
    }
    
    double findKthMin(vector<int>& numsA,int startA,vector<int>& numsB,int startB,int k,int lenA,int lenB){
        if(lenA-startA<lenB-startB){
            return findKthMin(numsB,startB,numsA,startA,k,lenB,lenA);
        }
        if(lenB-startB==0){
            return numsA[startA+k-1];
        }
        if(k==1){
            return min(numsA[startA],numsB[startB]);
        }
        int cutB=min(k/2,lenB-startB);
        int cutA=k-cutB;
        if(numsA[startA+cutA-1]<numsB[startB+cutB-1]){
            return findKthMin(numsA,startA+cutA,numsB,startB,k-cutA,lenA,lenB);
        }
        else if(numsA[startA+cutA-1]>numsB[startB+cutB-1]){
            return findKthMin(numsA,startA,numsB,startB+cutB,k-cutB,lenA,lenB);
        }
        else{
            return numsA[startA+cutA-1];
        }
    }
    
};

Java:

64ms

class Solution {
    public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1=nums1.length;  
        int len2=nums2.length;  
        int totalLen=len1+len2;  
        if(totalLen%2==1){  
            return findKthMin(nums1,0,nums2,0,totalLen/2+1,len1,len2);  
        }  
        else return (findKthMin(nums1,0,nums2,0,totalLen/2+1,len1,len2)+findKthMin(nums1,0,nums2,0,totalLen/2,len1,len2))*1.0/2;  

    }
    public static double findKthMin(int[] numsA,int startA,int[] numsB,int startB,int k,int lenA,int lenB){  
        if(lenA-startA<lenB-startB){  
            return findKthMin(numsB,startB,numsA,startA,k,lenB,lenA);  
        }  
        if(lenB-startB==0){  
            return numsA[startA+k-1];  
        }  
        if(k==1){  
            return Math.min(numsA[startA],numsB[startB]);  
        }  
        int cutB=Math.min(k/2,lenB-startB);  
        int cutA=k-cutB;  
        if(numsA[startA+cutA-1]<numsB[startB+cutB-1]){  
            return findKthMin(numsA,startA+cutA,numsB,startB,k-cutA,lenA,lenB);  
        }  
        else if(numsA[startA+cutA-1]>numsB[startB+cutB-1]){  
            return findKthMin(numsA,startA,numsB,startB+cutB,k-cutB,lenA,lenB);  
        }  
        else{  
            return numsA[startA+cutA-1];  
        }  
    }
      

}

Python:

在类的成员函数,都要在def的时候,参数第一个是self,在调用的时候都要用self.blabla

99ms 没用切片,击败55.36%

class Solution(object):
    def findKthMin(self,numsA,startA,numsB,startB,k,lenA,lenB):
        if(lenA-startA<lenB-startB):
            return self.findKthMin(numsB,startB,numsA,startA,k,lenB,lenA)

        if(lenB-startB==0):
            return numsA[startA+k-1]

        if(k==1):
            return min(numsA[startA],numsB[startB])
        cutB=min(k/2,lenB-startB)
        cutA=k-cutB
        if(numsA[startA+cutA-1]<numsB[startB+cutB-1]):
            return self.findKthMin(numsA,startA+cutA,numsB,startB,k-cutA,lenA,lenB)
        elif(numsA[startA+cutA-1]>numsB[startB+cutB-1]):
            return self.findKthMin(numsA,startA,numsB,startB+cutB,k-cutB,lenA,lenB)
        else:
            return numsA[startA+cutA-1]
        
    def findMedianSortedArrays(self,nums1, nums2):

        len1=len(nums1)
        len2=len(nums2)
        totalLen=len1+len2
        if (totalLen & 1):
            return self.findKthMin(nums1, 0, nums2, 0, totalLen / 2 + 1, len1, len2)
        else :
            return (self.findKthMin(nums1, 0, nums2,0,totalLen/2+1,len1,len2)+self.findKthMin(nums1, 0, nums2, 0,totalLen / 2, len1,len2)) * 1.0 / 2

用切片,发现效率是一样的,但是写起来简洁一些,以后用python能用切片就用切片了

class Solution(object):
    def findKthMin(self,numsA,numsB,k):
        if(len(numsA)<len(numsB)):
            return self.findKthMin(numsB,numsA,k)
        if(len(numsB)==0):
            return numsA[k-1]
        if(k==1):
            return min(numsA[0],numsB[0])
        cutB=min(k/2,len(numsB))
        cutA=k-cutB
        if(numsA[cutA-1]<numsB[cutB-1]):
            return self.findKthMin(numsA[cutA:],numsB,k-cutA)
        elif(numsA[cutA-1]>numsB[cutB-1]):
            return self.findKthMin(numsA,numsB[cutB:],k-cutB)
        else:
            return numsA[cutA-1]
        
    def findMedianSortedArrays(self,nums1, nums2):

        len1=len(nums1)
        len2=len(nums2)
        totalLen=len1+len2
        if (totalLen & 1):
            return self.findKthMin(nums1, nums2, totalLen / 2 + 1)
        else :
            return (self.findKthMin(nums1, nums2, totalLen/2+1) + self.findKthMin(nums1, nums2, totalLen / 2)) * 1.0 / 2

  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值