problem:

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

有两个排序好的数列num1和num大小为m和n

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

找到这两个数列中的中位数,其时间复杂度为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

solution:

中位数:就是有序数列中的一个数可以将数列分为长度相同的两个部分,且一个部分的所有值都大于这个数,另一部分的所有值都小于这个数,我们称这个数为中位数

 

既然是要找到中位数,那么正常遇到这种题,归并排序后再通过判断偶数和奇数来输出中位数就可以了,但是其时间复杂度并不符合要求

但是我们发现题目给出的两个数列是有序的,那么我们可以根据这个来进行划分,首先我们已知中位数可以将所有数列都分为长度相同的两个部分,那么我们可以假设

m+n/2为其中一半的长度,假设在num1这个数列中选取第i个数,那么对应的num2数列选取j个

其i,j满足i+j = m-i+n-j

那么j = (m+n)/2-i

当num1的第i+1个数小于num2的第j个数的时候说明i应该向右侧移动

当num2的第j+1个数小于num1的第i个数的时候说明i应该向左侧移动

于此同时所谓的移动其实是用的二分法,对num1进行二分,寻找i的最合适的位置

最合适也就是,只需要满足num1的第i+1个数大于num2的第j个,和num2的第j+1个大于num1的第i个

 

如果n+m为奇数,说明中位数为max(num1的第i个,num2第j个)

如果n+m为偶数,说明中位数为(max(num1的第i个,num2第j个)+min(num1的第i+1个,num2第j+1个))/2

代码如下:

 1 class Solution(object):
 2     def findMedianSortedArrays(self, nums1, nums2):
 3         """
 4         :type nums1: List[int]
 5         :type nums2: List[int]
 6         :rtype: float
 7         """
 8 
 9         m = len(nums1)
10         n = len(nums2)
11         if(m>n):
12             nums1,nums2,m,n = nums2,nums1,n,m
13         imin = 0
14         imax = m
15         halflen = (n+m+1)/2
16         while(imin <= imax):
17             i = (imin+imax)/2
18             j = halflen - i
19             if(i<imax and nums1[i]<nums2[j-1]): 
20                 imin = i+1
21             elif(i>imin and nums2[j]<nums1[i-1]):
22                 imax = i-1
23             else:
24                 maxleft = 0
25                 if(i==0):
26                     maxleft = nums2[j-1]
27                 elif(j==0):
28                     maxleft = nums1[i-1]
29                 else:
30                     maxleft = max(nums1[i-1],nums2[j-1])
31                 if((n+m)%2==1):
32                     return maxleft
33                 minright = 0
34                 if(i == m):
35                     minright = nums2[j]
36                 elif(j == n):
37                     minright = nums1[i]
38                 else:
39                     minright = min(nums1[i],nums2[j])
40 
41                 return (minright+maxleft)/2.0

 

posted on 2018-02-02 19:02  Qarnet  阅读(79)  评论(0)    收藏  举报