【18.寻找两个正序数组的中位数】

79 阅读1分钟

题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

示例 1:

输入: nums1 = [1,3], nums2 = [2]
输出: 2.00000
解释: 合并数组 = [1,2,3] ,中位数 2

题解

方式一:暴力

复杂度:O(nlogn)

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int len1 = nums1.length;
    int len2 = nums2.length;
    int[] tem = new int[len1 + len2]; // 把两个数组合到一个
    for (int i = 0; i < len1; i++) {
        tem[i] = nums1[i];
    }
    for (int i = len1; i < tem.length; i++) {
        tem[i] = nums2[i - len1];
    }
    Arrays.sort(tem); // 排序 nlogn
    double ans = 0.0;
    if (tem.length % 2 == 0) {
        ans = (tem[tem.length / 2 - 1] + tem[tem.length / 2]) / 2.0;
    } else {
        ans = tem[tem.length / 2];
    }
    return ans;
}

方式二:双指针

给的两个数组是正序的 复杂度:O(n)

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int l1 = nums1.length;
    int l2 = nums2.length;
    int[] tem = new int[l1 + l2]; // 创建一个大数组
    int p1 = 0;
    int p2 = 0;
    int cur = 0;
    // 利用双指针按序给大数组赋值,直到中点位置
    while (cur <= tem.length / 2) {
        if (p1 >= l1) {
            tem[cur++] = nums2[p2++];
        } else if (p2 >= l2) {
            tem[cur++] = nums1[p1++];
        } else if (nums1[p1] < nums2[p2]) {
            tem[cur++] = nums1[p1++];
        } else {
            tem[cur++] = nums2[p2++];
        }
    }
    // 到这里cur = tem.length / 2 + 1;
    double ans = 0.0;
    if ((l1 + l2) % 2 == 0) {
        ans = (tem[cur - 2] + tem[cur -1]) / 2.0;
    } else {
        ans = tem[cur - 1];
    }
    return ans;
}

方式三:二分

应该还有一种解法,因为题目要求复杂度 log,但是想不出来

总结

算法:排序双指针