leetcode-4 寻找两个正序数组的中位数(Hard)

题目描述

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。
 

示例 1:

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

则中位数是 2.0

示例 2:

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

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

给定代码

class Solution {
    public double findMedianSortedArrays(int[] num1, int[] num2) {
        
    }
}

题解一

暴力破解,先合并,再排序。
根据总数奇偶,取中间一个数或两个数。
全程调用API。

class Solution {
    public double findMedianSortedArrays(int[] A, int[] B) {
		int [] result = new int[A.length + B.length];
		// 将A和B合并
		System.arraycopy(A, 0, result, 0, A.length);
		System.arraycopy(B, 0, result, A.length, B.length);
		// 排序
		Arrays.sort(result);

		int len = A.length + B.length;
		return (len & 1) == 0 ? (result[len / 2 - 1] + result[len / 2]) / 2.0 : result[len / 2];
	}
}

时间复杂度: O ( ( n + m ) l o g ( n + m ) ) O((n + m)log(n + m)) O((n+m)log(n+m)) n n n m m m分别为两个数组的长度,合并耗时 O ( n + m ) O(n + m) O(n+m),排序耗时 O ( ( n + m ) l o g ( n + m ) ) O((n + m)log(n + m)) O((n+m)log(n+m))

空间复杂度: O ( n + m ) O(n + m) O(n+m),开的result数组空间为 n + m n + m n+m

题解二

从小往大读,读到中位数时停下来并返回结果。

class Solution {
    public double findMedianSortedArrays(int[] A, int[] B) {
        int m = A.length;
        int n = B.length;
        int len = m + n;
        // right记录当前遍历的数,left记录上一个数
        int left = -1, right = -1;
        int aStart = 0, bStart = 0;
        for (int i = 0 ; i <= len / 2 ; i++)
        {
            left = right;
            if (aStart < m && (bStart >= n || A[aStart] < B[bStart]))
            {
                right = A[aStart++];
            }
            else
            {
                right = B[bStart++];
            }
        }

        if ((len & 1) == 0)
            return (left + right) / 2.0;
        else
            return right;
    }
}

时间复杂度: O ( m + n ) O(m + n) O(m+n),需要遍历 ( m + n ) / 2 (m + n) / 2 (m+n)/2次。

空间复杂度: O ( 1 ) O(1) O(1)。不需要额外开空间。

题解三

来自力扣大佬的思路:

要达到题目的 O ( l o g ( m + n ) ) O(log(m + n)) O(log(m+n)),只有通过二分的方法来解决了。
题目的求中位数,可以理解为求第 k k k 小的数。( k = ( m + n ) / 2 k = (m + n)/2 k=(m+n)/2

由于数组是有序的,其实可以每次排除 k / 2 k / 2 k/2个数。
在这里插入图片描述我们比较两个数组的第 k/2 个数字,如果 k 是奇数,向下取整。也就是比较第 3 个数字,上边数组中的 4 和下边数组中的 3,如果哪个小,就表明该数组的前 k/2 个数字都不是第 k 小数字,所以可以排除。也就是 1,2,3 这三个数字不可能是第 7 小的数字,我们可以把它排除掉。将 134945678910 两个数组作为新的数组进行比较。
在这里插入图片描述然后k减去排除了的数目后,在进行类似比较。每次排除大约k/2,就能达到题目所给的复杂度要求。

具体代码没有实现。可以参考力扣题解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值