• 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
        
    
  • 相关阅读:
    三种基本排序算法
    sourcetree push限制大小
    移动端布局注意事项
    margin-top 实效问题
    布局方式
    web前端开发工程师
    eScript 简记
    Siebel script for Pre Events
    Siebel Performance for Script <1>
    Siebel Presumed Child Property Set
  • 原文地址:https://www.cnblogs.com/weedboy/p/7146996.html
Copyright © 2020-2023  润新知