LeetCode2: Median of Two sorted array.

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

public class Solution {
    
    private double median(int A[]){
        int mid = A.length/2;
        if(A.length%2 == 1)
            return A[mid];
        else
            return ((double)A[mid-1] + (double)A[mid])/2;
    }
    
    
    public double findMedianSortedArrays(int A[], int B[]) {
        // Start typing your Java solution below
        // DO NOT write main() function
        if(A == null || B == null)
            return 0;
        
        int midA = 0;
        int midB = 0;
        
        if(A.length == 0 && B.length == 0)
            return 0;

        if(A.length == 0)
            return median(B);
            
        if(B.length == 0)
            return median(A);

        int cut = 0;
        while(true){
            if(A.length <= 2||B.length <=2){
                int [] tmp = new int[A.length+B.length];
                int ndxA=0;
                int ndxB=0;
                for(int i=0; i<tmp.length; i++){
                    if(ndxB==B.length || (ndxA<A.length && A[ndxA]<=B[ndxB])){
                        tmp[i]=A[ndxA];
                        ndxA++;
                    }
                    else{
                        tmp[i]=B[ndxB];
                        ndxB++;
                    }
                }
                return median(tmp);
            }
            
            midA = A.length/2;
            midB = B.length/2;
            
            if(A.length%2 == 0)
                midA --;
                
            if(B.length%2 == 0)
                midB --;
            
            cut = midA<=midB?midA:midB;
            
            if(A[midA] == B[midB]){
                if((A.length%2 ==0) && (B.length%2 ==0))
                    return ((double)A[midA] + (double)(A[midA+1]<B[midB+1]?A[midA+1]:B[midB+1]))/2;
                else
                    return A[midA];
            }
            else if(A[midA] < B[midB]){
                A = Arrays.copyOfRange(A, cut, A.length);
                B = Arrays.copyOfRange(B, 0, B.length - cut);                    
            }
            else{
                A = Arrays.copyOfRange(A, 0, A.length-cut);
                B = Arrays.copyOfRange(B, cut, B.length);
            }
        }
    }
}


Bugs encountered:

1. Median of {a,b,c,d} is (b+c)/2

2. (double) 5/2  to get 2.5 instead of 2.0

 

------------------------------------------------------------------------------------------------------------------------------------------ 

LL's solution:

public class Solution {
    
    public static int[] merge(int A[],int B[]){
        //NOTE: A[] len = 1 or 2
        int lenA = A.length;
        int lenB = B.length;
        int[] C = new int[lenA+lenB];
        int i = 0, j = 0;
        while(i<lenA && j < lenB){
            if(B[j]<A[i]){
                C[i+j] = B[j];
                j++;
            }
            else{
                C[i+j] = A[i];
                i++;
            }
        }
        if(i==lenA){
            while(j<lenB){
                C[i+j] = B[j];
                j++;
            }
        }        
        else{
            while(i<lenA){
                C[i+j] = A[i];
                i++;
            }
        }
        return C;
    }
    
    public static double getMedian(int B[]){
        double median;
        int lenB = B.length;
        if(lenB==0)
            return 0;

        //B is even
        if(lenB%2 == 0){
            int mid1 = B[lenB/2-1];
            int mid2 = B[lenB/2];
            median = 1.0*(mid1+mid2)/2;
        }
        //B is odd
        else{
            int mid = B[(lenB-1)/2];
            median = mid;
        }
        return median;
    }
    
    public static double findMedian(int A[], int B[]){
        //NOTE: A[] len = 1 or 2
        int lenB = B.length;
        int lenA = A.length;
            
        double median;
                
        if(lenB==0)
            return getMedian(A);
                
        return getMedian(merge(A,B));
    }
    
    public static double findMedianSortedArrays(int A[], int B[]) {
        // Start typing your Java solution below
        // DO NOT write main() function
        int lenA = A.length;
        int lenB = B.length;
        double median;
        
        if(lenA ==0 && lenB ==0)
            return 0;
        if(lenA <= 2){
            median = findMedian(A,B);
            return median;
        }
        if(lenB <= 2){
            median = findMedian(B,A);
            return median;
        }
        
        //shrink array if max and min in the same list
        if(A[0]<B[0] && A[lenA-1]>B[lenB-1]){           
            int start = 0;
            int end = lenA-1;
            while(A[start]<B[0] && A[end]>B[lenB-1]){
                start++;
                end--;
            }
            A = Arrays.copyOfRange(A,start,end+1);
        }        
        else if(B[0]<A[0] && B[lenB-1]>A[lenA-1]){           
            int start = 0;
            int end = lenB-1;
            while(B[start]<A[0] && B[end]>A[lenA-1]){
                start++;
                end--;
            }
            B = Arrays.copyOfRange(B,start,end+1);
        }
        
        //start bineary search
        double midA = getMedian(A);
        double midB = getMedian(B);
        lenA = A.length;
        lenB = B.length;
        if(lenA==0)
        	return getMedian(B);
        if(lenB==0)
        	return getMedian(A);
        if(midA>midB){
            //safe to remove last half of A, and first half of B
            //But only remove len = short array/2
            int len = (lenA<lenB)?lenA:lenB;
            int cut;
            //len is even
            if(len%2 == 0)
                cut = len/2-1;           
            //len is odd
            else
                cut = (len-1)/2;
            
            A = Arrays.copyOfRange(A,0,lenA-cut);
            B = Arrays.copyOfRange(B,cut,lenB);   
            median = findMedianSortedArrays(A,B);           
        }
        else if(midA<midB){
            //safe to remove last half of B, and first half of A
            //But only remove len = short array/2
            int len = (lenA<lenB)?lenA:lenB;
            int cut;
            //len is even
            if(len%2 == 0)
                cut = len/2-1;           
            //len is odd
            else
                cut = (len-1)/2; 
            
            B = Arrays.copyOfRange(B,0,lenB-cut);
            A = Arrays.copyOfRange(A,cut,lenA);
            median = findMedianSortedArrays(A,B);            
        }
        else{
            //midA = midB
            median = midA;
        }
        
        return median;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值