一开始想到的方法是两个指针顺序查找,时间复杂度O(m+n)。后来看了网上的大神做法,用二分查找。
曲线救国。先找到前面k-1个数字,即A[1,2,...p]和B[1,2,...,q]的个数p+q=k-1。由此可见q=k-1-p,使用二分查找找到q即可,时间复杂度为O(lgn)。
二分查找终止条件:B[q]<=A[p]<=B[q+1] 或者 A[p]<=B[q]<=A[p+1]
关键点:由于数组下标是从0开始计算的,因此可以在数组的两头分别加上一个最小值和一个最大值来处理边界问题。这个也是参照某位大神的方法。
//two sorted array, find kth minimum value in the two arrays
public class KthMinInteger {
public static void main( String args[] ){
int array1[] = new int []{3,4,5,111,222,333};
int array2[] = new int []{22,44,88,111,222};
//int k = 5;
for( int k=0; k<13;k++ )
System.out.println("Kth minimum integer = "+ kthMinValue(array1, array2, k) );
}
public static int kthMinValue( int a1[], int a2[], int k ){
int size1 = a1.length;
int size2 = a2.length;
if( k<=0 || k>size1+size2 )
return Integer.MIN_VALUE;
//add min value in the front of both two arrays
//add max value at the end of both two arrays
int newArray1[] = new int[size1+2];
int newArray2[] = new int[size2+2];
newArray1[0]=newArray2[0]=Integer.MIN_VALUE;
newArray1[size1+1]=newArray2[size2+1]=Integer.MAX_VALUE;
for( int i=0; i<size1; i++ )
newArray1[i+1] = a1[i];
for( int i=0; i<size2; i++ )
newArray2[i+1] = a2[i];
//binary search
int start = 0;
int end = size1+1;
int index1=0;
int index2=0;
while( start<=end ){
index1 = (start+end)/2 ;
index2 = k-1-index1;
if( index2<0 )
end = index1;
else if( index2>=size2+1 )
start = index1;
else{
if( fit(newArray1[index1],newArray2[index2],newArray2[index2+1]) || fit(newArray2[index2],newArray1[index1],newArray1[index1+1]) )
break;
if( newArray1[index1]>newArray2[index2] )
end = index1;
else
start = index1;
}
}
return Math.min(newArray1[index1+1], newArray2[index2+1]);
}
public static boolean fit(int a, int b, int c ){
if( a>=b && a<=c )
return true;
return false;
}
}