zoukankan      html  css  js  c++  java
  • LeetCode:Median of Two Sorted Arrays

    题目链接

    There are two sorted arrays A and B 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)).

    求两个有序数组的中位数,如果总元素个数是偶数,中位数是中间两个元素的平均值

    详细讲解请参考我的另一篇博文:求两个有序数组的中位数或者第k小元素,那篇博文中如果数组总元素个数是偶数,求的是上中位数。

    对于那篇博文中的算法2,这一题不能简单的套用,因为如果按照算法2的删除规则,当元素个数是偶数时,有可能把某个中位数删除了,比如对于数组【3,4】,【1,2,5,6】,比较4、5后就会把第一个数组中的3删除,但是3是要参与中位数的计算的。因此对于偶数个数的数组,我们加了一些判断,但是很复杂,代码如下,这里不推荐这种做法

     1 class Solution {
     2 public:
     3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
     4         int mid_a = m/2, mid_b = n/2;
     5         if(m == 0)
     6         {
     7             if(n % 2 == 0)
     8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
     9             else return B[mid_b];
    10         }
    11         else if(n == 0)
    12         {
    13             if(m % 2 == 0)
    14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
    15             else return A[mid_a];
    16         }
    17     
    18         if(m == 1)
    19         {
    20             if(n == 1)
    21                 return (A[0] + B[0]) / 2.0;
    22             if(n % 2 == 0)
    23             {
    24                 if(A[0] >= B[mid_b])
    25                     return B[mid_b];
    26                 else if(A[0] <= B[mid_b-1])
    27                     return B[mid_b-1];
    28                 else return A[0];
    29             }
    30             else
    31             {
    32                 if(A[0] >= B[mid_b+1])
    33                     return (B[mid_b] + B[mid_b+1]) / 2.0;
    34                 else if(A[0] <= B[mid_b-1])
    35                     return (B[mid_b] + B[mid_b-1]) / 2.0;
    36                 else return(B[mid_b] + A[0]) / 2.0;
    37             }
    38         }
    39         else if(n == 1)
    40         {
    41             if(m % 2 == 0)
    42             {
    43                 if(B[0] >= A[mid_a])
    44                     return A[mid_a];
    45                 else if(B[0] <= A[mid_a-1])
    46                     return A[mid_a-1];
    47                 else return B[0];
    48             }
    49             else
    50             {
    51                 if(B[0] >= A[mid_a+1])
    52                     return (A[mid_a] + A[mid_a+1]) / 2.0;
    53                 else if(B[0] <= A[mid_a-1])
    54                     return (A[mid_a] + A[mid_a-1]) / 2.0;
    55                 else return(A[mid_a] + B[0]) / 2.0;
    56             }
    57         }
    58         
    59         bool flag = false;
    60         if(m == 2 && n%2 == 0)
    61         {
    62                 if(A[0] <= B[0] && A[1] >= B[n-1])
    63                     return (B[mid_b] + B[mid_b-1]) / 2.0;
    64                 else if(A[0] >= B[0] && A[1] <= B[n-1])
    65                     return findMedianSortedArrays(A, m, &B[1], n-2);
    66                 flag = true;
    67         }
    68         else if(n == 2 && m%2 == 0)
    69         {
    70                 if(B[0] <= A[0] && B[1] >= A[m-1])
    71                     return (A[mid_a] + A[mid_a-1]) / 2.0;
    72                 else if(B[0] >= A[0] && B[1] <= A[m-1])
    73                     return findMedianSortedArrays(&A[1], m-2, B, n);
    74                 flag = true;
    75         }
    76         
    77     
    78             int cutLen = mid_a > mid_b ? mid_b:mid_a;
    79             if(m%2 == 0 && n%2 == 0 && flag == false)cutLen--;
    80             if(A[mid_a] == B[mid_b])
    81             {
    82                 if(m%2 == 0 && n%2 == 0)
    83                     return (A[mid_a] + max(A[mid_a-1], B[mid_b-1])) / 2.0; 
    84                 else 
    85                     return (A[mid_a] + B[mid_b]) / 2.0;
    86             }
    87             else if(A[mid_a] < B[mid_b])
    88                 return findMedianSortedArrays(&A[cutLen], m - cutLen, B, n - cutLen);
    89             else return findMedianSortedArrays(A, m - cutLen, &B[cutLen], n-cutLen);
    90         
    91     }
    92 };
    View Code

    我们可以对那篇博客中算法2稍作修改就可以求下中位数,因此当两个数组总元素时偶数时,求上中位数和下中位数,然后求均值

      1 class Solution {
      2 public:
      3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
      4         int mid_a = m/2, mid_b = n/2;
      5         if(m == 0)
      6         {
      7             if(n % 2 == 0)
      8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
      9             else return B[mid_b];
     10         }
     11         else if(n == 0)
     12         {
     13             if(m % 2 == 0)
     14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
     15             else return A[mid_a];
     16         }
     17         
     18         if((m+n) % 2)
     19             return helper_up(A, m, B, n);
     20         else return (helper_up(A, m, B, n) + helper_down(A, m, B, n)) / 2.0;
     21     }
     22     int helper_up(int A[], int m, int B[], int n)
     23     {
     24         int mid_a = m/2, mid_b = n/2;
     25         if(m == 1)
     26         {
     27             if(n == 1)
     28                 return A[0] < B[0] ? B[0] : A[0];
     29             if(n % 2 == 0)
     30             {
     31                 if(A[0] >= B[mid_b])
     32                     return B[mid_b];
     33                 else if(A[0] <= B[mid_b-1])
     34                     return B[mid_b-1];
     35                 else return A[0];
     36             }
     37             else
     38             {
     39                 if(A[0] >= B[mid_b+1])
     40                     return B[mid_b+1];
     41                 else if(A[0] <= B[mid_b])
     42                     return B[mid_b];
     43                 else return A[0];
     44             }
     45         }
     46         else if(n == 1)
     47         {
     48             if(m % 2 == 0)
     49             {
     50                 if(B[0] >= A[mid_a])
     51                     return A[mid_a];
     52                 else if(B[0] <= A[mid_a-1])
     53                     return A[mid_a-1];
     54                 else return B[0];
     55             }
     56             else
     57             {
     58                 if(B[0] >= A[mid_a+1])
     59                     return A[mid_a+1];
     60                 else if(B[0] <= A[mid_a])
     61                     return A[mid_a];
     62                 else return B[0];
     63             }
     64         }
     65         else
     66         {
     67             int cutLen = mid_a > mid_b ? mid_b:mid_a;//注意每次减去短数组的一半,如果数组长度n是奇数,一半是指n-1/2
     68             if(A[mid_a] == B[mid_b])
     69                 return A[mid_a];
     70             else if(A[mid_a] < B[mid_b])
     71                 return helper_up(&A[cutLen], m - cutLen, B, n - cutLen);
     72             else return helper_up(A, m - cutLen, &B[cutLen], n-cutLen);
     73         }
     74     }
     75     
     76     int helper_down(int A[], int m, int B[], int n)
     77     {
     78         int mid_a = (m-1)/2, mid_b = (n-1)/2;
     79         if(m == 1)
     80         {
     81             if(n == 1)
     82                 return A[0] < B[0] ? A[0] : B[0];
     83             if(n % 2 == 0)
     84             {
     85                 if(A[0] >= B[mid_b+1])
     86                     return B[mid_b+1];
     87                 else if(A[0] <= B[mid_b])
     88                     return B[mid_b];
     89                 else return A[0];
     90             }
     91             else
     92             {
     93                 if(A[0] >= B[mid_b])
     94                     return B[mid_b];
     95                 else if(A[0] <= B[mid_b-1])
     96                     return B[mid_b-1];
     97                 else return A[0];
     98             }
     99         }
    100         else if(n == 1)
    101         {
    102             if(m % 2 == 0)
    103             {
    104                 if(B[0] >= A[mid_a+1])
    105                     return A[mid_a+1];
    106                 else if(B[0] <= A[mid_a])
    107                     return A[mid_a];
    108                 else return B[0];
    109             }
    110             else
    111             {
    112                 if(B[0] >= A[mid_a])
    113                     return A[mid_a];
    114                 else if(B[0] <= A[mid_a-1])
    115                     return A[mid_a-1];
    116                 else return B[0];
    117             }
    118         }
    119         else
    120         {
    121             int cutLen = (m/2 > n/2 ? n/2:m/2);//注意每次减去短数组的一半,如果数组长度n是奇数,一半是指n-1/2
    122             if(A[mid_a] == B[mid_b])
    123                 return A[mid_a];
    124             else if(A[mid_a] < B[mid_b])
    125                 return helper_down(&A[cutLen], m - cutLen, B, n - cutLen);
    126             else return helper_down(A, m - cutLen, &B[cutLen], n-cutLen);
    127         }
    128     }
    129 };
    View Code

    最优雅的方法是调用那篇博客中算法3求两个有序数组第k小元素的方法            本文地址

     1 class Solution {
     2 public:
     3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
     4         int mid_a = m/2, mid_b = n/2;
     5         if(m == 0)
     6         {
     7             if(n % 2 == 0)
     8                 return (B[mid_b] + B[mid_b-1]) / 2.0;
     9             else return B[mid_b];
    10         }
    11         else if(n == 0)
    12         {
    13             if(m % 2 == 0)
    14                 return (A[mid_a] + A[mid_a-1]) / 2.0;
    15             else return A[mid_a];
    16         }
    17         
    18         if((m+n) % 2)
    19             return findKthSmallest(A, m, B, n, (m+n+1)/2);
    20         else return (findKthSmallest(A, m, B, n, (m+n)/2) + findKthSmallest(A, m, B, n, (m+n)/2+1)) / 2.0;
    21     }
    22     //找到两个有序数组中第k小的数,k>=1
    23     int findKthSmallest(int vec1[], int n1, int vec2[], int n2, int k)
    24     {
    25         //边界条件处理
    26         if(n1 == 0)return vec2[k-1];
    27         else if(n2 == 0)return vec1[k-1];
    28         if(k == 1)return vec1[0] < vec2[0] ? vec1[0] : vec2[0];
    29         
    30         int idx1 = n1*1.0 / (n1 + n2) * (k - 1);
    31         int idx2 = k - idx1 - 2;
    32      
    33         if(vec1[idx1] == vec2[idx2])
    34             return vec1[idx1];
    35         else if(vec1[idx1] < vec2[idx2])
    36             return findKthSmallest(&vec1[idx1+1], n1-idx1-1, vec2, idx2+1, k-idx1-1);
    37         else
    38             return findKthSmallest(vec1, idx1+1, &vec2[idx2+1], n2-idx2-1, k-idx2-1);
    39     }
    40 };

    【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3675220.html

  • 相关阅读:
    Redis源码剖析(十一)AOF持久化
    Redis源码剖析(一)内存管理zmalloc
    Redis源码剖析(七)压缩列表
    PHP基础课程学习总结
    php标记,变量,常量
    内容控件
    WPF 面板
    OpenSSL SSL_read: Connection was reset, errno 10054
    Java Web 项目学习(三) 发布帖子 AJAX
    控件类(ControlAndFont)
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3675220.html
Copyright © 2011-2022 走看看