leetcode4. Median of Two Sorted Arrays

leetcode4. Median of Two Sorted Arrays

题意:

有两个已排序的数组nums1和nums2,数组大小分别为m和n。

找到两个排序数组的中位数。整体运行时间复杂度应为O(log(m + n))。

思路:

感觉这道题还是有点难的,主要是对时间复杂度要求有点无法适应。
找到两个已排序数组的中位数。
其实理解成一般性的问题的话,就是找到第k个大小的数字。
不做要求的话,可以直接归并排序的思路可以直接找出第k大的数字,但是要是在n很大而且k无线接近于n的时候,复杂度还是很高的。在优化一下话,可以先算k在n/2的左边还是右边在右边的话,可以反向找,这样最差的情况是O(n/2)=O(n),还是O(n),但是起码给了自己一个二分的思路。
log的复杂度一般都是二分的。想上面一样要是继续二分下去的,是可以让复杂度变成Log(n)的。

我们要找到两个数组合并起来第k大的元素的话,我们可以先试想一种最特殊的情况,便于理解,就是A,B的前面各自占有的K/2全都是一样的,那么结果不就是(A[K/2]+B[K/2])/2吗?要是A[K/2] < B[K/2] ,画一个图理解马上就可以发现,两个数组合并之后,真正的第k大的元素应该在B[K/2]的左侧或者A[K/2]的右侧,我们可以吧A[K/2]左侧的元素(假设舍去了i个元素)舍去,因为全都是比k要小的元素。然后我们继续寻找剩下的数组中第(K-i)大的元素。这样的循环复杂度是可以认为是O(log(m + n))
的。代码实现的时候要注意边界的情况。

ac代码:

C++

class Solution {
public:
    int getkth(vector<int>& s,vector<int> &l,int k){
        if(s.size()>l.size()) return getkth(l,s,k);
        if(!s.size()) return l[k-1];
        if(k==1) return min(s[0],l[0]);
        
        int i=min((int)s.size(),k/2),j=min((int)l.size(),k/2);
        if(s[i-1]>l[j-1]){
            vector<int> next;
            for(int u=j;u<l.size();u++)
                next.push_back(l[u]);
            //copy(l.begin()+j,l.end(),next.begin());
            return getkth(s,next,k-j);
        }
        else{
            vector<int> next;
            for(int u=i;u<s.size();u++)
                next.push_back(s[u]);
            //copy(s.begin()+i,s.end(),next.begin());
            return getkth(next,l,k-i);
        }
        return 0;
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int l=(nums1.size()+nums2.size()+1)/2;
        int r=(nums1.size()+nums2.size()+2)/2;
        return (getkth(nums1,nums2,l)+getkth(nums1,nums2,r))/2.0;
    }
};

python

class Solution:
    def findkth(self,nums1,nums2,k):
        if len(nums1)>len(nums2):
            return self.findkth(nums2,nums1,k)
        if len(nums1) == 0:
            return nums2[k-1]
        if k == 1:
            return min(nums1[0],nums2[0])
        
        n = min(k//2 ,len(nums1))
        m = min(k//2 ,len(nums2))
        if nums1[n - 1] > nums2[m - 1]:
            return self.findkth(nums1,nums2[m:],k-m)
        else:
            return self.findkth(nums1[n:],nums2,k-n)
            
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        k1 = len(nums1)+len(nums2)+1
        k2 = len(nums1)+len(nums2)+2
        return (self.findkth(nums1,nums2,k1//2)+self.findkth(nums1,nums2,k2//2))/2
    
原文地址:https://www.cnblogs.com/weedboy/p/7146996.html