两个不同长度的排序数组的中位数

时间:2018-01-18 22:29:31

标签: algorithm

我试图理解在O(log(n + m))中解决这个问题的算法,其中n和m是数组的长度。我已经冒昧地发布了这个算法的解释链接:

https://www.geeksforgeeks.org/median-of-two-sorted-arrays-of-different-sizes/

我很难彻底消化这个算法背后的想法。我可以看到,这个想法是将其中一个数组的长度减少到1或2,然后应用基本情况。基本情况是有道理的,但我想知道是否可以省略n = 2的基本情况并且只是在n = 1上工作。我也不了解剩下的情况部分。我觉得我们必须将数组B []从开头切换到idx,这看起来很奇怪。这很奇怪,因为idx可以等于B []的长度,所以我们会忽略整个数组。

3 个答案:

答案 0 :(得分:2)

TL; DR:

主要思想是你可以删除肯定小于(或等于)数字集中位数的N个元素,只要你删除肯定大于或等于的相同数量。

让我们用一个例子解释一下:

A = [1 2 3 9 10],B = [3 4 5 6 7 8 9]

标有中间元素:

A = [1 2 3 9 10],B = [3 4 5 6 7 8 9]

总体中位数将在3到6之间(包括3和6)。因此,如果我们删除两个小于3的元素和两个大于6的元素,我们仍然会有相同的中位数。我们从A中删除的较小元素,以及B中较大的元素:

A = [3 9 10],B = [3 4 5 6 7]

现在我们删除一个大于9的元素(来自A)和一个小于5的元素(来自B):

A = [3 9],B = [4 5 6 7]

我们达到了案例4(较小的数组有2个元素):算法要求

的中位数

B [M / 2],B [M / 2 - 1],max(A [0],B [M / 2 - 2]),min(A [1],B [M / 2 + 1] ])

是B [2],B [1],max(A [0],B [0]),min(A [1],B [3])

为6,5,max(3,4),min(9,7)

[6 5 4 7]

该数组的中位数为5.5。这是正确的结果。

答案 1 :(得分:1)

对我来说,这只是几分钟的几行python代码,它通过了leetcode检查,运行时超过了Python3在线提交的62%。我的代码在这里:


class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        n = len(nums1) + len(nums2)
        nums1.extend(nums2)  # merge two lists
        nums1.sort()  # sort it
        if n % 2 == 0:
            return (nums1[n//2-1] + nums1[n//2])/2 # return the median for even n
        else:
            return nums1[n//2] # return the median for odd n

答案 2 :(得分:0)

def findmedian(A,B):
    if len(A) > len(B):
        return findmedian(B,A)# always ensuring that we do the binsearch on the shorter arr
    x = len(A)
    y = len(B)
    start = 0# start and end of shorter arr
    end = x
    while (start <= end):
        partition_x = (start + end)//2# the mid of smaller arr, partition_x is an index
        partition_y = (x+y+1)//2 - partition_x# the suitable partition of larger arr to divide the arrs into equal halves
        if partition_x == 0:# if there is nothing on the left
            left_x = None
        if partition_x == x:# if there is nothing on the right
            right_x = sys.maxint# +inf
        if partition_y == 0:
            left_y = None# this is -inf similar to the case for smaller arr
        if partition_y == y:
            right_y = sys.maxint

        if (left_x <= right_y) and (left_y <= right_x):# all the elems on left are smaller than all the elems on right is ensured by
         #checking on the extremes only since arrs sorted. Also, the partition always makes equal halves, so found the right spot.
            if (x+y) % 2 == 0:
                return (max(left_x,left_y) + min(right_x,right_y))/2.0
            else:
                return max(left_x,left_y)# if the num of elems is odd
            elif left_x > right_y:# if we have come more towards right of smaller arr, then move left on smaller arr
                end = partition_x -1
            else:# if we have come more to the left
                start = partition_x + 1