4 Median of Two Sorted Arrays

Concept

Part 1 - 不斷比較nums1跟nums2的中位數,砍掉一半的元素

  • 這題基本的概念是想要不斷砍掉一半的元素,讓搜尋變得很有效率。
  • 問題是,要怎麼怎麼知道哪一些元素是我們可以忽略的?
  • 基本想法是,只要不可能是我們最後想求的中位數,就可以忽略。
  • 下一個問題是,要怎麼知道哪些元素不可能是我們想求的中位數?
  • 先隨意觀察兩個矩陣,我們知道ans是4。

     nums1 = [1, 2, 5, 7]
     nums2 = [3, 4, 8]
    
  • 不過知道答案是4的目的不是要讓我們想到可以解出答案的演算法,現在只是要先確保我們砍掉一半的元素不會誤砍到4。

  • 因為已經參考了答案,知道要取兩個矩陣的中位數。
  • nums1的中位數是$$(2+5)/2=3.5$$,意義是可以將nums1分成兩半,一半比3.5大,一半比3.5小。
  • nums2的中位數是4,用途也是將nums2切成兩半。
  • 在這個例子中,nums1的中位數 < nums2的中位數。
  • 我們想求的ans可以將nums1跟nums2切成兩半,意義是,總共有一半的元素比ans小、一半比ans大。
  • 所以ans不可能落在nums1的左半邊,不然就會有超過一半的元素比ans大;同理,也不可能落在nums2的右半邊,不然就會有超過一半的元素比ans小。

Part 2 - 確保可以求得答案的演算法

  • 雖然有了上面的concept,但還沒有可以求得答案的感覺。
  • 從最上層的來看,我們不知道nums1+nums2的元素有奇數還是偶數個。所以寫一個general的方法直接考慮兩種case。
  • 如果共有奇數個,l==r;如果共有偶數個,l==r-1。只要getkth(A, 0, B, 0, l)跟getkth(A, 0, B, 0, r)都能傳回對的答案,那答案就會對。
    public double findMedianSortedArrays(int[] A, int[] B) {
          int m = A.length, n = B.length;
          int l = (m + n + 1) / 2;
          int r = (m + n + 2) / 2;
          return (getkth(A, 0, B, 0, l) + getkth(A, 0, B, 0, r)) / 2.0;
      }
    
  • 有一個疑問是,getkth()的參數為什麼是這樣?
    double getkth(int[] A, int aStart, int[] B, int bStart, int k)
    
  • 首先要了解,getkth()的目的是什麼?
  • getkth()的目的就是要取到A跟B矩陣中第k大的元素。
  • 所以最上層是呼叫getkth(A, 0, B, 0, l)跟getkth(A, 0, B, 0, r),取得第l大跟第r大的元素。
  • 因為我們需要取到A跟B裡面第k大的element,所以把A跟B傳進去是必要的。
  • 接下來的再一次呼叫,因為已經排除掉

============= 待整理

  • 因為現在是要找第k大的element,而且其實我們傳進來的k的大小會是中位數的那一格(例如總共有7個element,那k就會是4)。所以中位數的取法就是aMid = A[aStart + k/2 - 1];,然後aStart + k/2 - 1 < A.length只是要檢查大小不要超過array長度。

     if (aStart + k/2 - 1 < A.length) aMid = A[aStart + k/2 - 1];
    
  • 這邊是終止條件,首先如果aStart超過A的長度,表示現在只是在求B[bStart]這個index開始第k大的element。如果是k==1,表示已經砍到剩下要求目前最小的那個element了,而且分別是從A[aStart]跟B[bStart]開始求,所以自然就是取min(A[aStart], B[bStart])了。

if (aStart > A.length - 1) return B[bStart + k - 1];            
    if (bStart > B.length - 1) return A[aStart + k - 1];                
    if (k == 1) return Math.min(A[aStart], B[bStart]);

results matching ""

    No results matching ""