两有序序列中找第k大数O(lgm+lgn)

//  基本思想源于二分查找
import  java.util.Scanner;

public   class  Main  {    
    
public static int fd(int[] arrA, int al, int ar, int[] arrB, int bl, int br, int k) {
        
int am = (ar - al) / 2 + al;
        
int bm = (br - bl) / 2 + bl;
        
if( am+bm+2 < k+1 ) {
            
if( arrA[am+1< arrB[bm+1] ) {
                
if( ar-am == 1 ) am = ar;
                
return fd(arrA, am, ar, arrB, bl, br, k);
            }

            
if( br-bm == 1 ) bm = br;
            
return fd(arrA, al, ar, arrB, bm, br, k);
        }
 else if( am+bm+2 == k+1 ) {
            
if( arrA[am] == arrB[bm] ) return arrA[am];
            
if( arrA[am] < arrB[bm] ) {
                
if( bm==0 || arrA[am]>=arrB[bm-1] ) return arrB[bm];
                
if( arrA[am+1< arrB[bm] ) return fd(arrA, am, ar, arrB, bl, bm, k);
                
else return arrB[bm];
            }

            
// arrA[am] > arrB[bm]
            if( am==0 || arrA[am-1]<=arrB[bm] ) return arrA[am];
            
if( arrA[am] > arrB[bm+1] ) return fd(arrA, al, am, arrB, bm, br, k);
            
else return arrA[am];
        }
 else // am+bm+2 > k+1
            if( arrA[am] < arrB[bm] ) return fd(arrA, al, ar, arrB, bl, bm, k);
            
return fd(arrA, al, am, arrB, bl, br, k);
        }

    }

    
    
public static int findKMax(int[] arrA, int[] arrB, int k) {
        
// 处理零界情况 减少复杂度
        if( arrA[arrA.length-1< arrB[0] ) {
            
if( k < arrA.length ) return arrA[k];
            
else return arrB[k-arrA.length];
        }

        
if( arrB[arrB.length-1< arrA[0] ) {
            
if( k < arrB.length ) return arrB[k];
            
else return arrA[k-arrB.length];
        }

        
if( k<arrA.length && arrA[k]<arrB[0] ) return arrA[k];
        
if( k<arrB.length && arrB[k]<arrA[0] ) return arrB[k];
        
if( k>arrA.length && arrB[k-arrA.length]>=arrA[arrA.length-1] ) return arrB[k-arrA.length];
        
if( k>arrB.length && arrA[k-arrB.length]>=arrB[arrB.length-1] ) return arrA[k-arrB.length];
        
        
return fd(arrA, 0, arrA.length-1, arrB, 0, arrB.length-1, k);
    }

    
public static void main(String[] args) throws Exception {
        
int[] arrA = new int[10];
        
int[] arrB = new int[10];
        
        
for(int i = 0; i < 10; i++{
            arrA[i] 
= i;
            arrB[i] 
= i + 3;
        }

        
        Scanner scanner 
= new Scanner(System.in);
        
while(true{
            
int d = scanner.nextInt();
            System.out.printf(
"d = %d,  result = %d ", d, findKMax(arrA, arrB, d));
        }

        
//        for(int i = 0; i < 20; i++)
//            System.out.printf("i = %d,  result = %d ", i, findKMax(arrA, arrB, i));
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值