Median of Two Sorted Arrays

①原题

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

②乡村英语翻译一下

给你两个排序数组,容量为m的数组A,容量为n的数组B。求出两个数组的中位数(啥玩意?),硬性要求时间复杂度O(log (m+n)).算法

③读题

1:太汗颜了,median究竟是个啥,查一下:数组

中位数是在一组数据中居于中间的数(特别注意的地方是:这组数据以前已经通过升序排列!!!),即在这组数据中,有一半的数据比它大,有一半的数据比它小。若是这组数据包含偶数个数字,中值是位于中间的两个数的平均值。spa

2:好吧,中位数是这么个玩意,那么理论上首先咱们须要先将两个数组合为一,再求这个新合并的数组的中位数。翻译

3:可是,已经限定死了时间复杂度为log(m+n),原来LeetCode的题目也思路不开放嘛。code

4:问题能够转化成两个有序序列找第num大的数,因为时间复杂度已经限定死了,只能采用相似二分的思想,每一个步骤去掉一半数据元素。排序

④解题

  public class MedianofTwoSortedArrays2 {
    //先来一个蠢的,实现功能。其实效率仍是能够的嘛,只不过不符合算法要求,时间复杂度在于排序的 n*log(n)
    public static double findMedianLow(int A[], int B[]) {
        int[] sumArray = ArrayUtils.addAll(A, B);
        Arrays.sort(sumArray);
        int length = sumArray.length;
        if (length % 2 == 0) {
            double num1 = sumArray[length / 2];
            double num2 = sumArray[length / 2 - 1];
            return (num1 + num2) / 2;
        } else {
            return sumArray[length / 2];
        }
    }

    public static double findMedianSortedArrays(int A[], int B[]) {
        int m = A.length;
        int n = B.length;
        int total = m + n;
        //长度为积数取中间,为偶数去中间两个的平均值
        if ((total & 0x01) != 0) {
            return findMedian(A, m, B, n, total / 2 + 1);
        } else {
            return (findMedian(A, m, B, n, total / 2) + findMedian(A, m, B, n,
                    total / 2 + 1)) / 2.0;
        }
    }

    //二分法,每次都能去除掉一部分范围外数据。须要注意每次去除数据都会改变数组的结构,因此须要特殊处理临界值
    private static double findMedian(int A[], int m, int B[], int n, int target) {
        if (m == 0) {
            return B[target - 1];
        } else if (n == 0) {
            return A[target - 1];
        } else if (target == 1) {
            return A[0] < B[0] ? A[0] : B[0];
        }
        int temp = target / 2;
        if (Math.min(m, n) < temp) {
            temp = Math.min(m, n);
        }
        if (A[temp - 1] > B[temp - 1]) {
            return findMedian(A, m, Arrays.copyOfRange(B, temp, n), n - temp, target - temp);
        } else if (A[temp - 1] < B[temp - 1]) {
            return findMedian(Arrays.copyOfRange(A, temp, m), m - temp, B, n, target - temp);
        } else {
            return A[temp - 1];
        }
    }

    public static void main(String[] args) {
        int[] a = new int[10000];
        int[] b = new int[20000];
        for (int i = 0; i < 10000; i++) {
            a[i] = i + 1;
        }
        for (int i = 10000; i < 30000; i++) {
            b[(i - 10000)] = i + 1;
        }
        long nowTime = System.currentTimeMillis();
        System.out.println(MedianofTwoSortedArrays2.findMedianLow(a, b));
        System.out.println(System.currentTimeMillis() - nowTime);
        long nowTime1 = System.currentTimeMillis();
        System.out.println(MedianofTwoSortedArrays2.findMedianSortedArrays(a, b));
        System.out.println(System.currentTimeMillis() - nowTime1);
    }
}
相关文章
相关标签/搜索