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。