LeetCode - Median of Two Sorted Arrays

本文介绍了一种复杂度为O(log(m+n))的算法来查找两个已排序数组的中位数,通过每次排除一半的元素实现效率提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题挺难的,一开始只想到了merge的做法,但这种方法是O(n)的。

后来在网上找到了O(lg(m+n))的方法,http://blog.youkuaiyun.com/yutianzuijin/article/details/11499917 ,本质就是每次排除k/2个数,再 k = k/2

链接里面给的代码是C++的,我转化成了java,主要就是原来函数传输的参数是数组长度,并且每次可以通过指针加减直接改数组的起始指针,但java不支持指针加减,所以这里改成了排除后剩下的数的起始index,注意,这里要访问剩下数组的第k个值时,一定要加上起始index了,比如 A[startA+k-1],因为这个问题调试了好久。。。。。。

代码如下:

public class Solution {
    public double findMedianSortedArrays(int A[], int B[]) {
        int total= A.length + B.length;
        if(total%2 == 0){
            return (findKth(A, 0, B, 0, total/2)+findKth(A, 0, B, 0, total/2+1))/2;
        }
        else{
            return findKth(A, 0, B, 0, total/2+1);
        }
    }
    
    public double findKth(int[] a, int startA, int[] b, int startB, int k){
        int m = a.length - startA;
        int n = b.length - startB;
        //always assume m<=n
        if(m>n){
            return findKth(b, startB, a, startA, k);
        }
        if(m==0) return b[startB+k-1];
        if(k==1) return Math.min(a[startA], b[startB]);
        
        int pa = Math.min(m, k/2);
        int pb = k-pa;
        
        if(a[startA+pa-1] < b[startB+pb-1]){
            return findKth(a, startA+pa, b, startB, k-pa);
        }
        else if(a[startA+pa-1] > b[startB+pb-1]){
            return findKth(a, startA, b, startB+pb, k-pb);
        }
        else{
            return b[startB+pb-1];
        }
    }
}

在最好情况下,每次都有k一半的元素被删除,所以算法复杂度为log k ,由于求中位数时k为(m+n)/2,所以算法复杂度为log(m+ n )。

增加C++代码:

class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) {
        int size = m+n;
        if(size%2==0){
            return ((double)(findKthValue(A, m, B, n, size/2)+findKthValue(A, m, B, n, size/2+1)))/2;
        }
        else return findKthValue(A, m, B, n, size/2+1);
    }
    
    int findKthValue(int A[], int m, int B[], int n, int k){
        if(m>n) return findKthValue(B, n, A, m, k);
        if(m==0) return B[k-1];
        if(k==1) return min(A[0], B[0]);
        int t = min(k/2, m);
        int q = k-t;
        if(A[t-1] <= B[q-1]){
            return findKthValue(A+t, m-t, B, n, k-t);
        }
        else{
            return findKthValue(A, m, B+q, n-q, k-q);
        }
    }
};


写C++代码感觉很爽,没有JAVA语句那么冗长累赘。。。但是,指针什么的弄乱了就太烦了。。。所以这两种语言还是各有好处吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值