Median of Two Sorted Arrays -- LeetCode
阿新 • • 發佈:2018-11-19
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
原題連結: http://oj.leetcode.com/problems/median-of-two-sorted-arrays/這道題比較直接的想法就是用
接下來我們考慮有沒有優化的演算法。優化的思想來源於order statistics,在演算法導論10.3節中提到。問題等價於求兩個array的第k=(m+n)/2(假設m和n分別是兩個陣列的元素個數)大的數是多少。基本思路是每次通過檢視兩個陣列的第k/2大的數(假設是A[k/2],B[k/2]),如果兩個A[k/2]=B[k/2],說明當前這個數即為兩個陣列剩餘元素的第k大的數,如果A[k/2]>B[k/2], 那麼說明B的前k/2個元素都不是我們要的第k大的數,反之則排除A的前k/2個,如此每次可以排除k/2個元素,最終k=1時即為結果。總的時間複雜度為O(logk),空間複雜度也是O(logk),即為遞迴棧大小。在這個題目中因為k=(m+n)/2,所以複雜度是O(log(m+n))。比起第一種解法有明顯的提高,程式碼如下:
public double findMedianSortedArrays(int A[], int B[]) { if((A.length+B.length)%2==1) return helper(A,B,0,A.length-1,0,B.length-1,(A.length+B.length)/2+1); else return (helper(A,B,0 ,A.length-1,0,B.length-1,(A.length+B.length)/2) +helper(A,B,0,A.length-1,0,B.length-1,(A.length+B.length)/2+1))/2.0;}private int helper(int A[], int B[], int i, int i2, int j, int j2, int k){ int m = i2-i+1; int n = j2-j+1; if(m>n) return helper(B,A,j,j2,i,i2,k); if(m==0) return B[j+k-1]; if(k==1) return Math.min(A[i],B[j]); int posA = Math.min(k/2,m); int posB = k-posA; if(A[i+posA-1]==B[j+posB-1]) return A[i+posA-1]; else if(A[i+posA-1]<B[j+posB-1]) return helper(A,B,i+posA,i2,j,j+posB-1,k-posA); else return helper(A,B,i,i+posA-1,j+posB,j2,k-posB);}
實現中還是有些細節要注意的,比如有時候剩下的數不足k/2個,那麼就得剩下的,而另一個數組則需要多取一些數。但是由於這種情況發生的時候,不是把一個數組全部讀完,就是可以切除k/2個數,所以不會影響演算法的複雜度。
這道題的優化演算法主要是由order statistics派生而來,原型應該是求topK的演算法,這個問題是非常經典的問題,一般有兩種解法,一種是用quick select(快速排序的subroutine),另一種是用heap。 複雜度是差不多的,有興趣可以搜一下,網上資料很多,topK問題在海量資料處理中也是一個非常經典的問題,所以還是要重視。