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);
    }
}
相關文章
相關標籤/搜索