【LeetCode】4.Median of Two Sorted Arrays 两个排序数组的中位数

示例 1:

nums1 = [1, 3]
nums2 = [2]

中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

中位数是 (2 + 3)/2 = 2.5

解题思路:

糟糕- -没理解题意,首先需要知道“中位数”的含义,其次,题目对时间复杂度做了要求,必须为O(log (m+n))。
先写理解的代码,猜测题意:

nums = sorted(nums1 + nums2)
lenth = len(nums)
if lenth % 2 == 0:
    return (nums[lenth//2] + nums[lenth//2 - 1]) / 2
else:
    return nums[lenth//2]

116 ms,打败了47.53%的对手。

[沉思],也就是说,我对题目的理解是正确的,本题确实要输出两个排序数组最中间的数。
本题的难点在于排序算法,
我用Python自带sorted排序算法就不对了,我需要找到尽可能快的排序算法并写出。

解题思路1:

排序有多种方式,在网上可以轻易搜到。
但本题的重点,是排序两个有序数组。
我想,用一个数组挨个往另一个数组里插是个不错的选择。
如图:

..............画的什么鬼图.................
代码:

nums = nums1 + nums2
for i in range(len(nums1), len(nums)):
    for j in range(i, -1, -1):
        if nums[i] < nums[j]:
            nums[i], nums[j] = nums[j], nums[i]
            i = j
# print(nums)
lenth = len(nums)
if lenth % 2 == 0:
    return (nums[lenth // 2] + nums[lenth // 2 - 1]) / 2
else:
    return nums[lenth // 2]

然则............Time Limit Exceeded............
也对....sorted排序是底层语言写的...我这排序又怎么能快过它.............
所以,要么有更快速的排序,要么,这道题真正的做法不是排序。

解题思路2:

仔细思考一下,这道题并不需要生成排序的数组- -只是要找到中位数罢了。

        lenth = len(nums1) + len(nums2)
        loc = lenth // 2 - 1
        print(loc)
        i, j, count = 0, 0, 0

        while i < len(nums2) and j < len(nums1) and count != loc:
            if nums2[i] > nums1[j]:
                j = j + 1
            else:
                i = i + 1
            count = j + i

        if i == len(nums2):
            median = nums1[lenth // 2 - i]
            if lenth % 2 == 0:
                prevMedian = nums1[lenth // 2 - i - 1]
        elif j == len(nums1):
            median = nums2[lenth // 2 - j]
            if lenth % 2 == 0:
                prevMedian = nums2[lenth // 2 - j - 1]
        elif count == loc:
            if nums2[i] > nums1[j]:
                prevMedian = nums1[j]
                j = j + 1
            else:
                prevMedian = nums2[i]
                i = i + 1
            if i == len(nums2):
                median = nums1[lenth // 2 - i]
            elif j == len(nums1):
                median = nums2[lenth // 2 - j]
            elif nums2[i] > nums1[j]:
                median = nums1[j]
                j = j + 1
            else:
                median = nums2[i]
                i = i + 1

        # print(i, j, prevMedian, median)
        if lenth % 2 == 0:
            return ((prevMedian + median) / 2)
        else:
            return median

148 ms,打败了31.36%的对手。
更重要的是- -我写的真恶心........

如果说这个算法有什么缺点的话,那应该是从中间比较而不是从最初比较。
来看一下官方解题思路..

解题思路3:

这道题官方甚至给了Python代码。
而且- -没有用模除,修改后的代码如下:

        m, n = len(nums1), len(nums2)
        if m > n:
            nums1, nums2, m, n = nums2, nums1, n, m
        if n == 0:
            raise ValueError

        imin, imax, half_len = 0, m, (m + n + 1) // 2
        while imin <= imax:
            i = (imin + imax) // 2
            j = half_len - i
            if i < m and nums2[j-1] > nums1[i]:
                # i is too small, must increase it
                imin = i + 1
            elif i > 0 and nums1[i-1] > nums2[j]:
                # i is too big, must decrease it
                imax = i - 1
            else:
                # i is perfect

                if i == 0: max_of_left = nums2[j-1]
                elif j == 0: max_of_left = nums1[i-1]
                else: max_of_left = max(nums1[i-1], nums2[j-1])

                if (m + n) % 2 == 1:
                    return max_of_left

                if i == m: min_of_right = nums2[j]
                elif j == n: min_of_right = nums1[i]
                else: min_of_right = min(nums1[i], nums2[j])

                return (max_of_left + min_of_right) / 2.0

144ms,打败了35.78%的对手。
很好,这个故事告诉我们,请消停的排序,不要满脑子骚操作。
这个算法与我的找中位数的算法不同为:
.........就是完全一样,只是我是从最小开始比,这个算法是从中间开始比。下次我注意。

解题思路4:

来看一下讨论区,有没有哪位前辈分享代码。
...............................没找到更好的算法.........................莫非是我英语水平不够?
前面的53%的用户到底是怎么做的?
待我查查其他博客文章。
这篇文章使用了nums.append(nums1.pop(0))的方法来排序,只花了112ms。
我终于学到了如何查看更快的算法,原来是直接点击柱状图就可以。

猜你喜欢

转载自blog.csdn.net/tiantuanzi/article/details/83862790
今日推荐