Leetcode 4. Median of Two Sorted Arrays 笔记

183 阅读1分钟

Hard

思路

  • merge array最直接, 但是时间复杂度为O(m + n) ,超时
  • 为满足log级别的时间复杂度,采用binary search
  • 二分法找到

过程

  • 确定较短数组, 作为a(对较短数组做二分查找时间更短)
  • corner case, A长度为0, 直接返回B的中位数
  • 中位数(不论奇偶),公式:
((double)B[(lenB - 1) / 2] + (double)B[lenB / 2]) / 2
  • 求A的左半边元素(Aend + AStart)/2 ,B的左半边元素(B的为(len + 1)/2 - cutA, +1 的原因为当总长度为奇数时直接return最右边元素
  • 得到L1, L2, R1, R2
  • 更新分割线,判断(L1 > R2) : end = cutA -1 (L2 > R1) : start = cutA + 1
  • 如果都满足,说明分割线找对, 可以返回
  • 偶数: L1,L2 的MAX + R1,R2的MAX /2

代码

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int[] A = nums1;
        int[] B = nums2;
        if(A.length > B.length) 
            return findMedianSortedArrays(B, A);
        
        int lenA = A.length, lenB = B.length, len = lenA + lenB;
        if(A.length == 0) 
            return ((double)B[(lenB - 1)/2] + (double)B[(lenB)/2]) / 2;
        int start = 0, end = lenA;
        int cutA, cutB;
        while(start <= end){
            cutA = (start + end) /2 ;
            cutB = (len + 1) / 2 - cutA;
            double L1 = (cutA == 0)?Integer.MIN_VALUE:A[cutA - 1];
            double R1 = (cutA == lenA)?Integer.MAX_VALUE:A[cutA];
            double L2 = (cutB == 0)?Integer.MIN_VALUE:B[cutB - 1];
            double R2 = (cutB == lenB)?Integer.MAX_VALUE:B[cutB];
            
            if(L1 > R2){
                end = cutA - 1;
            }else if(L2 > R1){
                start = cutA + 1;
            }else {
                if(len % 2 == 0){
                    return (Math.max(L1,L2) + Math.min(R1,R2)) / 2;
                 }else
                    return Math.max(L1,L2);}
                
        }
        return -1;
    }
}