两个排序数组取第k小的数字

一开始想到的方法是两个指针顺序查找,时间复杂度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;  
}


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值