LeetCode4. Median of Two Sorted Arrays(C++/Python)

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)).

You may assume nums1 and nums2 cannot be both empty.

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

解题思路:这道题记得是某年408计算机联考的算法题原题,题目要求复杂度为O(log(m+n)),一般来讲排序数组的操作我们可以通过二分法或其他方式将复杂度从线性降低到log,本题也一样,不妨动动二分法的脑筋。

目标:找到最后合并数组的中位数(思考的时候先假设合并),如果为偶数,则要求中间两位的平均数,可以发现不管是总长度为奇数还是偶数,最终结果都可以写做是合并数组的第m+n+1位和第m+n+2位的平均数。

具体过程:现在假设我们要找的是合并数组的第k位,不论最终第k位是在num1中,还是num2中找到的,一个有一个数组的前k/2个元素是无效的元素,具体是哪个数组,则需要看num1的k/2处和num2的k/2处元素值哪个大,较小的那一个数组的前k/2个元素一定无效,接下来的问题则变成了,在去除无效数组的前k/2和另一个数组中,求他们最终合并数组的第k - k/2处的数。

C++

class Solution {
public:
    int m, n;
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        m = nums1.size();
        n = nums2.size();
        int left = (m + n + 1) >> 1, right = (m + n + 2) >> 1;
        return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
    }
    int findKth(vector<int>&nums1, int i, vector<int>&nums2, int j, int k){
        if(i >= m)
            return nums2[j + k - 1];
        if(j >= n)
            return nums1[i + k - 1];
        if(k == 1)
            return min(nums1[i], nums2[j]);
        int midVal1 = (i + k / 2 - 1 < m) ? nums1[i + k/2 - 1] : INT_MAX;
        int midVal2 = (j + k / 2 - 1 < n) ? nums2[j + k/2 - 1] : INT_MAX;
        return midVal1 < midVal2 ? findKth(nums1, i + k/2, nums2, j, k - k/2) : findKth(nums1, i, nums2, j + k/2, k - k/2);
    }
};

Python

import sys
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        self.nums1 = nums1
        self.nums2 = nums2
        self.m = len(nums1)
        self.n = len(nums2)
        self.findKth(0, 0, (self.m+self.n+1) / 2)
        num = self.ans
        self.findKth(0, 0, (self.m+self.n+2) / 2)
        return (num+self.ans) / 2.0
    def findKth(self, i, j, k):
        if i >= self.m:
            self.ans = self.nums2[j+k-1]
            return
        if j >= self.n:
            self.ans = self.nums1[i+k-1]
            return
        if k == 1:
            self.ans = min(self.nums1[i], self.nums2[j])
            return
        midVal1 = self.nums1[i+k/2-1] if (i + k / 2 - 1 < self.m) else sys.maxint
        midVal2 = self.nums2[j+k/2-1] if (j + k / 2 - 1 < self.n) else sys.maxint
        return self.findKth(i+k/2, j, k-k/2) if midVal1 < midVal2 else self.findKth(i, j+k/2, k-k/2)
        

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值