1. 程式人生 > >兩個有序陣列中位數

兩個有序陣列中位數

大小m和n分別有兩個排序陣列A和B。找到兩個排序陣列的中值。總的執行時間複雜度應該是O(log(m+n))。

  1. class Solution {  
  2. public:  
  3.     /** 
  4.      * @param A: An integer array. 
  5.      * @param B: An integer array. 
  6.      * @return: a double whose format is *.5 or *.0 
  7.      */
  8.     double findMedianSortedArrays(vector<int> A, vector<int> B) {  
  9.       int
     m=A.size(),n=B.size();  
  10.       int s=m+n;  
  11.       if(s&0x01)//真為奇數
  12.           return findKth(A,B,0,0,m,n,s/2+1);  
  13.       else
  14.       {  
  15.           double a=findKth(A,B,0,0,m,n,s/2);  
  16.           double b=findKth(A,B,0,0,m,n,s/2+1);  
  17.           return (a+b)/2;  
  18.       }  
  19.          // return (findKth(A,B,0,0,m,n,s/2)+findKth(A,B,0,0,m,n,s/2+1))/2;
  20.     }  
  21. private:  
  22.     double findKth(vector<int> A, vector<int> B,int start1,int start2,int m,int n,int k)//start1,start2代表每個vector起始的下標;m,n代表各vector剩餘的元素個數
  23.     {  
  24.         //保證A是較短的陣列,因為會出現陣列長度小於k/2的情況,所以根據較小陣列來定另一個數組
  25.         if(m>n)//m代表A的長度,n代表B的長度
  26.             return findKth(B,A,start2,start1,n,m,k);  
  27.         if(m==0)//m=0即代表陣列arr1中已經沒有元素了,所以中位數從B中找
  28.             return B[start2+k-1];//下標加start2的原因是不一定是從下標0開始,可能下標0到start2的元素已經被拋棄
  29.         if(k==1)  
  30.             return min(A[start1],B[start2]);  
  31.         int x=min(k/2,m),y=k-x;//記錄兩組中位數下標
  32.         if(A[start1+x-1]<B[start2+y-1])  
  33.             return findKth(A,B,start1+x,start2,m-x,n,k-x);//start1+x表示捨棄x個不可能的元素,m-x表示將x個元素
  34.                                                           //剔除掉陣列,k-x表示這x個元素已經被剔除,接下來中位數表示第k-x個元素
  35.         else
  36.             if(A[start1+x-1]>B[start2+y-1])  
  37.                 return findKth(A,B,start1,start2+y,m,n-y,k-y);//<span style="font-family:Arial, Helvetica, sans-serif;">start2+y表示捨棄y前的元素</span>
  38.             else
  39.                 return A[start1+x-1];  
  40.     }//本題捨棄的均為各自陣列所選下標之前的元素
  41. };