[LeetCode][H0004]尋找兩個有序數組的中位數(Java)(二分or雙指針)

題目描述:

給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2。

請你找出這兩個有序數組的中位數,並且要求算法的時間複雜度爲 O(log(m + n))。

你可以假設 nums1 和 nums2 不會同時爲空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

則中位數是 2.0


示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

則中位數是 (2 + 3)/2 = 2.5


反思錯誤:

①二分 做的話,各種需要注意腳標的地方……超級混亂,最後除二 指向的哪裏都不知道了。

解題思路:

一、先說說二分的思路吧:(官方題解 說是遞歸法,我覺得說二分更妥當)

既然是找中位數,那麼首先明確 中位數 左邊的數 的個數 一定等於 右邊的數 的個數 。

好,這樣的話,我們只需要關注最短的數組就可以了,,,爲什麼?看下邊。

當我們取 短數組的 i 位置時,要保證中位數左右個數相等,那麼長數組 必定 要取 (nums1.length + nums.length) / 2 - i 位置【我這裏只是爲了方便理解,這麼寫的,事實不一定】,,,

而且先取短數組 的好處 在於 長數組就可定不會 越界!!【因爲長數組的長度一定大於一半】

然後就是對短數組 進行 二分,比較,再分………………不想說了,二分我覺得太亂。

二、說說下邊這個方法:(我覺得特好理解)

同樣的,中位數 左右兩邊的 個數 相等。

那先建一個數組 res 長度爲 總長一半 加一;

剩下的就簡單了;;;循環唄,看nums1小  還是 nums2 小,誰小,,數組res就把誰放進去

那麼最後  總和奇數個 返回res[總長一半]

總數偶數個 返回 ( res[總長一半 - 1] + res[總長一半] )/ 2.0

Java代碼(二分):

class Solution {
  public double findMedianSortedArrays(int[] A, int[] B) {
  	int m = A.length;
      int n = B.length;
      if (m > n) { // to ensure m<=n
          int[] temp = A; A = B; B = temp;
          int tmp = m; m = n; n = tmp;
      }
      int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
      while (iMin <= iMax) {
          int i = (iMin + iMax) / 2;
          int j = halfLen - i;
          if (i < iMax && B[j-1] > A[i]){
              iMin = i + 1; // i is too small
          }
          else if (i > iMin && A[i-1] > B[j]) {
              iMax = i - 1; // i is too big
          }
          else { // i is perfect
              int maxLeft = 0;
              if (i == 0) { maxLeft = B[j-1]; }
              else if (j == 0) { maxLeft = A[i-1]; }
              else { maxLeft = Math.max(A[i-1], B[j-1]); }
              if ( (m + n) % 2 == 1 ) { return maxLeft; }

              int minRight = 0;
              if (i == m) { minRight = B[j]; }
              else if (j == n) { minRight = A[i]; }
              else { minRight = Math.min(B[j], A[i]); }

              return (maxLeft + minRight) / 2.0;
          }
      }
      return 0.0;
  }
}

Java代碼(雙指針):

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int lenhalf = (len1+len2)/2;
        boolean isOdd = (len1+len2)%2 != 0;
        return search(nums1,nums2,lenhalf,isOdd);
    }
    double search(int[] nums1,int[] nums2,int lenhalf,boolean isOdd){
        int[] res = new int[lenhalf+1];
        int indexPoint1 = 0,len1 = nums1.length;
        int indexPoint2 = 0,len2 = nums2.length;
        for(int i=0;i<=lenhalf;++i){
            if(indexPoint2==len2 || (indexPoint1<len1 && nums1[indexPoint1]<nums2[indexPoint2]))
                res[i] = nums1[indexPoint1++];
            else if(indexPoint2<len2)
                res[i] = nums2[indexPoint2++];
        }
        if(isOdd)
            return res[lenhalf];
        else
            return (res[lenhalf-1]+res[lenhalf])/2.0;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章