您的位置:首页 > 其它

LeetCode - Median of Two Sorted Arrays

2015-03-24 01:23 344 查看
这道题挺难的,一开始只想到了merge的做法,但这种方法是O(n)的。

后来在网上找到了O(lg(m+n))的方法,/article/1536805.html ,本质就是每次排除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语句那么冗长累赘。。。但是,指针什么的弄乱了就太烦了。。。所以这两种语言还是各有好处吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: