1. 程式人生 > >Median of Two Sorted Arrays -- LeetCode

Median of Two Sorted Arrays -- LeetCode

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                原題連結:  http://oj.leetcode.com/problems/median-of-two-sorted-arrays/  
這道題比較直接的想法就是用
Merge Sorted Array
這個題的方法把兩個有序數組合並,當合併到第(m+n)/2個元素的時候返回那個數即可,而且不用把結果陣列存起來。演算法時間複雜度是O(m+n),空間複雜度是O(1)。因為程式碼比較簡單,就不寫出來了,跟 Merge Sorted Array 比較類似,大家可以參照這個題目的解法。

接下來我們考慮有沒有優化的演算法。優化的思想來源於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問題在海量資料處理中也是一個非常經典的問題,所以還是要重視。
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述