leetcode Median of Two Sorted Arrays

265 篇文章 1 订阅
231 篇文章 0 订阅

There are two sorted arrays A and B 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)).

Best Solution by Binary Search:

Before writting codes,  we should understand the following things:

  1. The median of any ascending array is (num[ceiling((len-1)/2)]+num[ceiling(len/2)])/2. Mark cut (l,r)=(num[ceiling((len-1)/2)],num[ceiling(len/2)])/2). 
  2. For two sorted arrays, the corresponding cuts are cut1(l1,r1), cut2(l2,r2). If l1<=r2 and l2<=r1, the final median is (max(l1,l2)+min(r1,r2))/2
  3. However, item 2 won't always happen. If we adjust cut1 to one direction and cut2 to opposite direction until l1<=r2 and l2<=r1, we could stil find the final median (max(l1,l2)+min(r1,r2))/2
  4. Initially, cut1(l1,r1)=(num[ceiling((len1-1)/2)],num[ceiling(len1/2)])/2), cut2(l2,r2)=(num[ceiling((len2-1)/2)],num[ceiling(len2/2)])/2), final merged array cut is (num[ceiling((len1+len2-1)/2)],num[ceiling((len1+len2)/2)])/2). The question is that if updated (l1,r1) is (num[ceiling((len1-1-x)/2)],num[ceiling((len1-x)/2)])/2), what's updated cut2 to ensure (l1,r1), (l2,r2) could find the final median? The answer is updated cut2 = (num[ceiling((len2+x-1)/2)],num[ceiling((len2+x)/2)])/2), which could be understanded as move x elements from array1 to array2 but the final median won't change
  5. Consider some corner cases:
  6. So the task becomes how to find appropriate cut index (ceiling((len1-1-x)/2), ceiling((len1-x)/2)) in order to make l1<=r2 and l2<=r1, we could do binary search ref to https://blog.csdn.net/taoqick/article/details/23260157. Understand the range of start+off is closed interval [0, len]
  7. (ceiling((len-1)/2), ceiling((len1)/2)) and (ceiling((len1)/2), ceiling((len1+1)/2)) are different and look like walking half step. It seems that we move left leg with one step and draw close the other leg. In order to support the half step and ceiling((len1-1)/2 ranging in closed interval [-1, len1-1], the search range for len1 should be closed [0,2len1]. We could finish the codes now.
import sys
class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        n1, n2 = len(nums1), len(nums2)
        if (n1 < n2):
            return self.findMedianSortedArrays(nums2, nums1)
        #You may assume nums1 and nums2 cannot be both empty
        left, right = 0, n2*2
        l1_i,r1_i,l2_i,r2_i = 0,0,0,0
        while (left <= right):

            mid = left+(right-left)//2 #range from [0, 2*n2]

            l2_i,r2_i = (mid-1)//2, mid//2 #l2_i ranges from [-1, n2-1], r2_i ranges from [0, n2]
            l1_i,r1_i = (n1+n2-mid-1)//2, (n1+n2-mid)//2 #l1_i ranges from [-1, n1-1], r1_i ranges from [0, n1]

            l2, r2 = nums2[l2_i] if l2_i >= 0 else -sys.maxsize, nums2[r2_i] if r2_i < n2 else sys.maxsize
            l1, r1 = nums1[l1_i] if l1_i >= 0 else -sys.maxsize, nums1[r1_i] if r1_i < n1 else sys.maxsize

            if (l1 > r2):
                left = mid+1
            elif (l2 > r1):
                right = mid-1
            else:
                return (max(l1, l2) + min(r1, r2)) / 2

        return (max(l1,l2) + min(r1,r2)) / 2

s = Solution()
print(s.findMedianSortedArrays([1,3],[2,4,5]))
print(s.findMedianSortedArrays([3,4,5,6],[1,2,3]))
print(s.findMedianSortedArrays([1,2],[3]))
print(s.findMedianSortedArrays([1,2],[3,4]))
print(s.findMedianSortedArrays([2,3,4],[1]))

 

Another solution:

The method of finding the kth number is easier than http://leetcode.com/2011/03/median-of-two-sorted-arrays.html . 

Take notice of A[pa - 1] instead of A[pa] because pa >= 1

class Solution {
 public:
  double findKth(int A[], int m, int B[], int n, int k) {
    if (m > n)
      return findKth(B, n, A, m, k);
    if (m == 0)
      return B[k-1];
    if (k == 1)
      return min(A[0], B[0]);
    int pa = min(m, k/2);
    int pb = k - pa;
    if (A[pa - 1] < B[pb - 1])
      return findKth(A + pa, m - pa, B, n , k - pa);
    else if (A[pa - 1] > B[pb - 1])
      return findKth(A, m, B + pb, n - pb, k - pb);
    else
      return A[pa - 1];
  }
  double findMedianSortedArrays(int A[], int m, int B[], int n) {
    int total = m + n;
    if (total % 2 == 0)
      return (findKth(A, m, B, n, total/2) + findKth(A, m, B, n, total/2 + 1))/2;
    else
      return findKth(A, m, B, n, total/2 + 1);
  }
};

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值