• [LeetCode #4] Median of Two Sorted Arrays


    There are two sorted arrays nums1 and nums2 of size m and n respectively.

    Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

     Example 1:

    nums1 = [1, 3]
    nums2 = [2]
    
    The median is 2.0
    

     Example 2:

    nums1 = [1, 2]
    nums2 = [3, 4]
    
    The median is (2 + 3)/2 = 2.5
    

     解法一: Merge first, and then find the median; O(m+n)

     1 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
     2     int totalsize = nums1Size + nums2Size;
     3     int *result = NULL;
     4     int i = 0, j = 0, k = 0;    
     5     double ret;
     6     
     7     if (totalsize == 0){
     8         return -1;
     9     }else{
    10         result = (int *)malloc(totalsize * sizeof(int));
    11     }
    12     
    13     if (result == NULL){
    14         return -1;
    15     }
    16     
    17     while( (i < nums1Size) && (j < nums2Size) ){
    18         if (nums1[i] < nums2[j]){
    19             result[k++] = nums1[i++];
    20         } else{
    21             result[k++] = nums2[j++];
    22         }
    23     }
    24     
    25     while (i < nums1Size){
    26         result[k++] = nums1[i++];
    27     }
    28     
    29     while (j < nums2Size){
    30         result[k++] = nums2[j++];
    31     }
    32 
    33     if ((totalsize % 2) == 1){
    34         ret = (double)(result[totalsize/2]);
    35     }else{
    36         ret = (double)((result[totalsize/2] + result[totalsize/2 - 1])) /2;
    37     }    
    38     
    39     free(result);
    40     
    41     return ret;
    42 }

    解法二: Binary search; O(log(m+n))

    "水中的鱼" (http://fisherlei.blogspot.com/search?q=median) 解释了如何用二分法做, 基本思想是在两个排序了的数组中求第K个数. 不过为何丢弃特定区间没有详细解释. 所以博主在这加以解释.

    借用以上文章的图片, 其结论加以修正后附加上分析是 (简单的说,就是或者丢弃最大中位数的右区间,或者丢弃最小中位数的左区间).

    1. If (m/2+n/2+1) >= k && a[m/2] >= b[n/2] , drop Section 2 以及 a[m/2];
       推理过程: a[m/2] 大于等于 b[n/2]表明 小与等于a[m/2]的数至少有 a[0] 到a[m/2-1]和b[0]到b[n/2], 一共是(m/2 + n/2 +1)个, 这个数大于等于k. 这表明a[m/2]以及其后的在数组a里的数不可能是第k个数, 所以可以被丢弃.
    2. If (m/2+n/2+1) >= k && a[m/2] <= b[n/2] , drop Section 4 以及b[n/2];
       推理过程: 类似 1.
    3. If (m/2+n/2+1) < k && a[m/2] <= b[n/2] ,  drop Section 1;
       推理过程: a[m/2] <= b[n/2]表明大于等于a[m/2]的数有 a[m/2+1]到a[m-1]以及b[n/2]到[b[n-1], 一共是(m/2 - 1 + n/2)个. 然后 (m/2-1+n/2) = (m+n) - (m+n)/2 - 1 = (m+n) - (m/2+n/2+1) > (m+n) - k. 所以这意味着a[0]到a[m/2]之间的数不包括第K个数, 因为对第K个数来说, 大与等于它的数有(m+n)-K个. 结论是a[0]到a[m/2]这个区间的数可以被丢弃.
    4. If (m/2+n/2+1) < k && a[m/2] >= b[n/2] ,  drop Section 3;
       推理过程: 类似 3
     
     1 int findKth(int a[], int m, int b[], int n, int k)  /* m 以及 n 是数组的长度 */
     2     {  
     3         if (m <= 0) return b[k-1];  
     4         if (n <= 0) return a[k-1];  
     5         if (k <= 1) return (a[0] <= b[0]) ? a[0] : b[0];   
     6     
     7         if ((n/2 + 1 + m/2) >= k)  
     8         {  
     9              if (b[n/2] >= a[m/2]) 
    10                   return findKth(a, m, b, n/2, k);  
    11              else  
    12                   return findKth(a, m/2,b, n, k);  
    13         }  
    14         else  
    15         {  
    16              if (b[n/2] >= a[m/2])  
    17                   return findKth(a + m/2 + 1, m - (m/2 + 1), b, n, k - (m/2 + 1));  
    18                   
    19              else  
    20                   return findKth( a, m, b + n/2 + 1, n - (n/2 + 1), k - (n/2 + 1));  
    21         }  
    22     }  
    23     
    24 double findMedianSortedArrays(int A[], int m, int B[], int n) {  
    25     if((n+m)%2 ==0)  
    26     {  
    27         return (findKth(A,m,B,n, (m+n)/2) + findKth(A,m,B,n, (m+n)/2+1))/2.0;  
    28     }  
    29     else{
    30         return findKth(A,m,B,n, (m+n)/2+1);        
    31     }
    32 }  
       
     
  • 相关阅读:
    如何写Makefile?
    C语言变量的存储类别详解
    Longest Palindrome Substring
    Count Primes
    Closest Binary Search
    Search Insert Position
    Set Matrix Zeros ****
    Search for a Range
    Two Sum II
    Jump Game
  • 原文地址:https://www.cnblogs.com/amadis/p/5904907.html
Copyright © 2020-2023  润新知