LeetCode - Median of Two Sorted Arrays

来源:互联网 发布:淘宝装修导航颜色代码 编辑:程序博客网 时间:2024/06/08 17:58

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

后来在网上找到了O(lg(m+n))的方法,http://blog.csdn.net/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一半的元素被删除,所以算法复杂度为logk,由于求中位数时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语句那么冗长累赘。。。但是,指针什么的弄乱了就太烦了。。。所以这两种语言还是各有好处吧。

0 0