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:
Copy nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
Copy nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
这题最直接的思路就是按 merge two sorted array 的办法,数出来一半的数字。但是那个时间复杂度是 O(m + n)。题目要求 O(log(m+n))
Copy class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
length = len(nums1) + len(nums2)
if length % 2 == 1:
return self.findKth(nums1, 0, nums2, 0, (length + 1) // 2) * 1.0
else:
return (self.findKth(nums1, 0, nums2, 0, length // 2)
+ self.findKth(nums1, 0, nums2, 0, length // 2 + 1)) / 2.0
def findKth(self, A, idxA, B, idxB, k):
if k == 1:
if idxA >= len(A):
return B[idxB]
elif idxB >= len(B):
return A[idxA]
else:
return min(A[idxA], B[idxB])
offset = k // 2 - 1
if idxA + offset >= len(A):
return self.findKth(A, idxA, B, idxB + offset + 1, k - k // 2)
elif idxB + offset >= len(B):
return self.findKth(A, idxA + offset + 1, B, idxB, k - k // 2)
elif A[idxA + offset] < B[idxB + offset]:
return self.findKth(A, idxA + offset + 1, B, idxB, k - k // 2)
else:
return self.findKth(A, idxA, B, idxB + offset + 1, k - k // 2)
Copy class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
length = len(nums1) + len(nums2)
if length % 2 == 1:
return self.findKth(nums1, nums2, (length + 1) // 2) * 1.0
else:
return (self.findKth(nums1, nums2, length // 2)
+ self.findKth(nums1, nums2, length // 2 + 1)) / 2.0
def findKth(self, A, B, k):
if not A:
return B[k - 1]
elif not B:
return A[k - 1]
lo, hi = min(A[0], B[0]), max(A[-1], B[-1])
while lo < hi: # 死记硬背
mid = (lo + hi) // 2 #
if self.countLessEqual(A, B, mid) >= k: #
hi = mid #
else: #
lo = mid + 1 #
return lo
def countLessEqual(self, A, B, value): # 算小于等于 value 的元素的个数
import bisect
return bisect.bisect(A, value) + bisect.bisect(B, value)
Copy class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
import sys
if len(nums1) == 0 and len(nums2) == 0:
return 0
m, n = len(nums1), len(nums2)
if m > n:
return self.findMedianSortedArrays(nums2, nums1)
lo, hi = 0, m
while lo <= hi:
cutIdx1 = (lo + hi) // 2
cutIdx2 = (m + n + 1) // 2 - cutIdx1
if cutIdx1 == 0:
maxLeft1 = nums2[cutIdx2 - 1]
else:
maxLeft1 = nums1[cutIdx1 - 1]
maxLeft1 = -sys.maxint - 1 if cutIdx1 == 0 else nums1[cutIdx1 - 1] # 这几行是为了处理 corner cases
maxLeft2 = -sys.maxint - 1 if cutIdx2 == 0 else nums2[cutIdx2 - 1] #
minRight1 = sys.maxint if cutIdx1 == m else nums1[cutIdx1] #
minRight2 = sys.maxint if cutIdx2 == n else nums2[cutIdx2] #
if maxLeft1 > minRight2:
hi = cutIdx1 - 1
elif maxLeft2 > minRight1:
lo = cutIdx1 + 1
else:
## maxLeft1 <= minRight2 and maxLeft2 <= minRight1. Found solution
if (m + n) % 2 == 1:
return max(maxLeft1, maxLeft2) * 1.0
else:
return (max(maxLeft1, maxLeft2) + min(minRight1, minRight2) ) / 2.0
print lo, hi
return 0