Leetcode - Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

这个题目要求运行时间复杂度必须是O(log(m+n)) ,所以要充分利用数组是已经排好序的特性。

网上有很多关于这个问题的分析,把这个问题转化为从两个排好序的数组中求第K 大的数。 具体思想,就是先以 K/2 为基准,看看 K/2 这些数是落在那个数组中,在循环/递归查找剩下的数。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len = nums1.size() + nums2.size();
        if(len %2 == 1) {
            return findKth(&nums1[0], nums1.size(), &nums2[0], nums2.size(), len /2 + 1) ;
        } else {
            return (findKth(&nums1[0], nums1.size(), &nums2[0], nums2.size(), len /2)
            + findKth(&nums1[0], nums1.size(), &nums2[0], nums2.size(), len /2 + 1) ) / 2.0;
        }
    }

函数 findKth 的非递归实现如下:

int findKth(int a[], int la, int b[], int lb, int k) {
        assert( la + lb >= k);
        int m, n;
        while(1) {
            if( la == 0 ) return b[k-1];
            if( lb == 0 ) return a[k-1];
            if( k == 1) return a[0] > b[0] ? b[0] : a[0] ;
            if( la + lb == k ) return a[0] > b[0] ? a[la-1] : b[lb-1] ;
            
            m = la > k/2 ? k/2 : la;
            n = lb > k - m ? k - m : lb ;
            
            if( m + n != k) {
                n = lb > k/2 ? k/2 : lb;
                m = k - n;
            }
            
            if(a[m-1] < b[n-1]) {
                a += m ;
                la -= m;
                k-= m ;
            } else if ( b[n-1] < a[m-1]) {
                b += n ;
                lb -= n;
                k -= n;
            } else {
                return a[m - 1] ;
            }
        }
    }

对于求第K 大的数,网上很多都是采用了递归的方法来实现,实现的代码:

int findKth(int a[], int m, int b[], int n, int k) {
        if( m == 0 ) return b[k-1];
        if( n == 0 ) return a[k-1];
        if(k == 1) return a[0] > b[0] ? b[0] : a[0] ;
        if( k == m + n) return a[m-1] > b[n-1] ? a[m-1] : b[n-1];
        
        if( m > n ) return findKth(b, n, a, m, k); //make sure m < n
        
        int la = m > k/2 ? k/2 : m;
        int lb = k - la;
    
        if(a[la-1] < b[lb-1] ) return findKth(a + la, m -la, b, n, k - la);
        else if( a[la-1] > b[lb-1]) return findKth(a, m, b + lb, n - lb, k -lb);
        else return a[la-1];
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值