代码改变世界

LeetCode刷题之Median of Two Sorted Arrays

  雪夜&流星  阅读(245)  评论(0编辑  收藏  举报

problem:

There are two sorted arrays A and B 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)).

寻找两个已排序数组的中位数,要求时间复杂度为 log(m+n).

 

第一种方法就是将两个数组合并,然后找出中位数:

复制代码
public class Solution {
    public static double findMedianSortedArrays(int A[], int B[]) {
        int m = A == null ? 0 : A.length;
        int n = B == null ? 0 : B.length;
        return findMedianSortedArrays(A, m, B, n);
    }

    public static double findMedianSortedArrays(int[] A, int m, int[] B, int n) {
        int i = 0, j = 0, median = m + n;
        double prev = 0, last = 0;
        if (median < 2) {
            if (m == 0 && n ==0) {
                return 0;
            } else if (m == 1) {
                return A[0];
            } else {
                return B[0];
            }
        }

        while ((i + j) <= (median / 2)) {
            prev = last;
            //如果A中的元素已经用完,直接取B数组
            if (i >= m) {
                last = B[j];
                j++;
            } else if (j >= n) { //如果B中的元素已经用完,直接取A数组
                last = A[i];
                i++;
            } else if (A[i] < B[j]) {
                last = A[i];
                i++;
            } else {
                last = B[j];
                j++;
            }
        }

        if ((median & 1) == 0) { //偶数个
            return (prev + last) / 2.0;
        } else { //奇数个
            return last;
        }
    }
}
复制代码

第二种方法,将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。

复制代码
public class Solution {
    public double findMedianSortedArrays(int A[], int B[]) {
        int lengthA = A.length;
        int lengthB = B.length;
        if ((lengthA + lengthB) % 2 == 0) {
            double r1 = (double) findMedianSortedArrays(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB) / 2);
            double r2 = (double) findMedianSortedArrays(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB) / 2 + 1);
            return (r1 + r2) / 2;
        } else
            return findMedianSortedArrays(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB + 1) / 2);
    }

    public int findMedianSortedArrays(int A[], int startA, int endA, int B[], int startB, int endB, int k) {
        int n = endA - startA;
        int m = endB - startB;

        if (n <= 0)
            return B[startB + k - 1];
        if (m <= 0)
            return A[startA + k - 1];
        if (k == 1)
            return A[startA] < B[startB] ? A[startA] : B[startB];

        int midA = (startA + endA) / 2;
        int midB = (startB + endB) / 2;

        if (A[midA] <= B[midB]) {
            if (n / 2 + m / 2 + 1 >= k)
                return findMedianSortedArrays(A, startA, endA, B, startB, midB, k);
            else
                return findMedianSortedArrays(A, midA + 1, endA, B, startB, endB, k - n / 2 - 1);
        } else {
            if (n / 2 + m / 2 + 1 >= k)
                return findMedianSortedArrays(A, startA, midA, B, startB, endB, k);
            else
                return findMedianSortedArrays(A, startA, endA, B, midB + 1, endB, k - m / 2 - 1);

        }
    }
}
复制代码

 

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示