求给定两个排序好的数组中第k大的数

这个问题比求两个长度相等的排序数组的上中位数难度要高一点,难就难在不是求中位数了,但是我们要学会举一反三,可以尝试通过分析将求第k大的数转化为求中位数。将数组中不可能的数排除,在剩下可能的数中求中位数,这样就会产生3情况:

首先声明:两个数组,长度唱的为lenl,长度短的为lens。

1.k<lens;

2.lens<k<lenl

3,lenl<k<lenl+lens

4.k<1或k>lenl+lens,报错

 

代码实现:

public class UpMedian{
    //求相同长度排序数组的中位数
    public static int getUpMedian(int[] arr1,int start1,int end1,int[] arr2,int start2,int end2) {
        if(arr1==null || arr1.length<=0 || arr2==null || arr2.length<=0) {
            System.out.println("Array is valid");
            return -1;
        }
        
        if(arr1.length!=arr2.length) {
            System.out.println("Array length is valid");
            return -1;
        }
        
        int middle1 = 0;
        int middle2 =0;
        //用来区分数组长度为奇偶数
        int offset = 0;
        
        while(start1 < end1) {
            middle1 = (start1+end1)>>1;
            middle2 = (start2+end2)>>1;
            offset = ((end1-start1+1)&1)^1;
            
            if(arr1[middle1] > arr2[middle2]) {
                end1=middle1;
                start2=middle2+offset;
            } else if(arr1[middle1] < arr2[middle2]) {
                start1 = middle1 +offset;
                end2 = middle2;
            } else {
                return arr1[middle1];
            }
        }
        
        return Math.min(arr1[start1], arr2[start2]);
    }

    public static int fingKthNum(int[] arr1, int[] arr2, int k) {
        if(arr1==null || arr2==null || arr1.length<=0 || arr2.length<=0) {
            throw new RuntimeException("Array is valid");
        }
        
        if(k<1 || k>(arr1.length+arr2.length)) {
            throw new RuntimeException("kth is valid");
        }
        
        int res = 0;
        int[] longs = arr1.length>arr2.length ?arr1 : arr2;
        int[] shorts = arr1.length>arr2.length ?arr2 : arr1;
        
        int l = longs.length;
        int s = shorts.length;
        
        if(k<=s) {
            res = getUpMedian(arr1, 0, k-1, arr2, 0, k-1);
        } else if(k<=l) {
            if(longs[k-s-1]>=shorts[s-1]) {
                res = longs[k-s-1];
            } else {
                res = getUpMedian(shorts, 0, s-1, longs, k-s, k-1);
            }
        } else if(k>l){
            if(longs[k-s-1]>=shorts[s-1]) {
                res = longs[k-s-1];
            } else if(shorts[k-l-1]>=longs[l-1]) {
                res = shorts[k-l-1];
            } else {
                res = getUpMedian(shorts, k-l, s-1, longs, k-s, l-1);
            }
        }
        return res;
    }
    

    public static void main(String[] args) {
        int[] a1 = {1,2,5,7};
        int[] a2 = {2,3,8,10};
        System.out.println(fingKthNum(a1, a2, 4));
    }
}

 

转载于:https://www.cnblogs.com/loren-Yang/p/7478716.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值