Median of Two Sorted Arrays

Date:

  Oct. 31, 2017

Problem:

  https://leetcode.com/problems/median-of-two-sorted-arrays/solution/

Description:

  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)).

  这题基本是抱着MissMary大佬的大腿做的,就不把满是补丁的代码丢上来献丑了。主要翻译一下大佬的核心思想。

  首先,我们要理解中位数的作用。在统计学中,中位数被用来“将一组数分为两个等长的部分,使得一个部分中的数总是大于另一部分”。

  如果我们理解了中位数在分割数组中的用途的话,我们离答案就很近了。

  首先将A数组切为两份,切点为i。

          left_A             |        right_A
    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]

  由于A有m个元素,所以A有m+1种切法,也就是说,i可以从0取到m。

  并且我们知道:

left_A的长度为i,right_A的长度为m-i
注意:当i=0,left_A为空,当i=m,right_A为空

  同样的,我们将B数组切为两份,切点为j。

  将left_A和left_B放在一起,right_A和right_B放在一起。姑且叫它们left_part和right_part。

          left_part          |        right_part
    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

  如果我们能确定:

left_part的长度等于right_part的长度
left_part的最大值小于等于right_part的最小值

  那么,我们就“将一组数分为两个等长的部分,使得一个部分中的数总是大于另一部分”了。这时候,中位数就在切点附近取得,比如说:

((max(left_part) + min(right_part)) / 2
或者
max(left_part)

  为了确保上面两个条件能实现,我们可以这样控制切点i,j:

1. i + j = m − i + n − j (或者 m - i + n - j + 1)
    如果n > m,我们就可以令i = 0 ~ m,而不必担心j越界。
2. A[i - 1] <= b[j], b[j - 1] <= a[i]

  于是我们需要做的只是不断对i进行二分查找,寻找符合条件的切点。

  值得关注的是i, j到达边界时的情形。在i = 0, j = 0, i = m, j = n的时候,A[i - 1], B[j - 1], A[i], B[j]可能不存在。

  这时我们不需要检查两个条件。举个例子,当i = 0,A[i - 1]不存在,所以不需要检查A[i - 1] <= b[j]。

  所以,总结一下:

1.(j = 0 or i = m or B[j - 1] <= A[i]) and (i = 0 or j = n or A[i - 1] <= B[j])
	此时我们可以停止搜索
2.j > 0 and i < m and B[j - 1] > A[i]
	此时i太小了,需要向后二分搜索
3.i > 0 and j < n and A[i - 1] > B[j]
	此时i太大了,需要向前二分搜索

  这个算法的复杂度为log(min(m, n))。

  好的,赞美大佬。今天没有submission。

原文地址:https://www.cnblogs.com/neopolitan/p/7763689.html