我的解法
- 思路:比较列表nums1中间和nums2中间的数,如果第一个列表小于第二个列表,那么不可能包含中间数的一串子序列总共有两串,nums1中间数前面的一串和nums2中间数后面的一串,比较长短,删除比较短的那一串(每次删掉其中一串序列的一半),不断递归,直到其中的一个列表长度缩短为2,然后插入排序(log级别),最后输出结果。
- 代码如下:
class Solution:
# @param {integer[]} nums1
# @param {integer[]} nums2
# @return {float}
# def __init__(self):
# self.count = 0
def findMedianSortedArrays(self, nums1, nums2):
#self.count += 1
#print self.count
endIndexOfNums1 = len(nums1) -1
endIndexOfNums2 = len(nums2) -1
#print 'nums1', nums1, 'nums2', nums2
if endIndexOfNums1 <= 1:
tmp = nums2
if endIndexOfNums1 == 0:
tmp = self.insertSort(nums1[0], nums2)
elif endIndexOfNums1 == 1:
tmp = self.insertSort(nums1[1], self.insertSort(nums1[0], nums2))
#print (tmp[len(tmp)/2] + tmp[(len(tmp) -1)/2]) /2, 'final tmp', tmp
ret = (tmp[len(tmp)/2] + tmp[(len(tmp) -1)/2]) /2.0
return ret
if endIndexOfNums2 <= 1:
return self.findMedianSortedArrays(nums2, nums1)
if nums1[endIndexOfNums1/2] <= nums2[endIndexOfNums2/2]:
if endIndexOfNums1 <= endIndexOfNums2:
return self.findMedianSortedArrays(nums1[endIndexOfNums1/2:], nums2[:endIndexOfNums2 - endIndexOfNums1/2 +1])
else:
return self.findMedianSortedArrays(nums2[:endIndexOfNums2/2 + 1], nums1[endIndexOfNums2 - endIndexOfNums2/2 :])
else:
return self.findMedianSortedArrays(nums2, nums1)
def insertSort(self, tmp, nums):
#print 'tmp', tmp, 'nums', nums
if len(nums) == 0:
nums = []
nums.append(tmp)
#print nums
return nums
if tmp == nums[len(nums)/2]:
return nums[:len(nums)/2 +1] + nums[len(nums)/2:]
elif tmp < nums[len(nums)/2]:
return self.insertSort(tmp, nums[:len(nums)/2]) + nums[len(nums)/2:]
else:
return nums[:len(nums)/2 +1] + self.insertSort(tmp, nums[len(nums)/2 +1:])
def main():
a = Solution()
print a.findMedianSortedArrays([1,2,3,4,5,6,7], [2, 4, 7, 9])
if __name__ == '__main__':
main()
- result: Time Limit Exceed
虽然是log(m) + log(n)级别的,但是还是超时了
思路二:
思路参考 直接从前面找,这个思路来自于找两串已排序的序列中的第k个大小的数。而且只排出前面的,后面的不考虑。具体来说:
Assume that the number of elements in A and B are both larger than k/2, and if we compare the k/2-th smallest element in A(i.e. A[k/2-1]) and the k-th smallest element in B(i.e. B[k/2 - 1]), there are three results:
(Becasue k can be odd or even number, so we assume k is even number here for simplicy. The following is also true when k is an odd number.)
A[k/2-1] = B[k/2-1]
A[k/2-1] > B[k/2-1]
A[k/2-1] < B[k/2-1]
if A[k/2-1] < B[k/2-1], that means all the elements from A[0] to A[k/2-1](i.e. the k/2 smallest elements in A) are in the range of k smallest elements in the union of A and B. Or, in the other word, A[k/2 - 1] can never be larger than the k-th smalleset element in the union of A and B.思路跟我上面的类似,但是时间还是少了很多,思路很棒!
代码如下:
class Solution:
# @param {integer[]} nums1
# @param {integer[]} nums2
# @return {float}
def findMedianSortedArrays(self, nums1, nums2):
total = len(nums1) + len(nums2)
if total % 2:
return self.findKth(nums1, nums2, total/2 +1)
else:
return (self.findKth(nums1, nums2, total/2) + self.findKth(nums1, nums2, total/2 +1))/2.0
def findKth(self, nums1, nums2, k):
if len(nums1) > len(nums2):
return self.findKth(nums2, nums1, k)
if len(nums1) == 0:
return nums2[k-1]
if k == 1:
return min(nums1[0], nums2[0])
partionOfnum1 = min(len(nums1), k/2)
partionOfnum2 = k - partionOfnum1
if nums1[partionOfnum1 -1] == nums2[partionOfnum2 -1]:
return nums1[partionOfnum1 -1]
elif nums1[partionOfnum1 -1] < nums2[partionOfnum2 -1]:
return self.findKth(nums1[partionOfnum1:], nums2, k -partionOfnum1)
else:
return self.findKth(nums1, nums2[partionOfnum2:], k -partionOfnum2)
- 结果:accepted