zoukankan      html  css  js  c++  java
  • 两个有序数组的中位数求解方法

    有两个已经升序排列的数组a[]和b[], 它们的长度分别为m和n,求这两个数组的中位数。注意,如果m+n为奇数,则中位数为正中间那个数; 如果m+n为偶数,则中位数为正中间两个数的平均值。这是一道很经典的面试题,本人在去VMware面试的时候被问到过,当时我只给出了O(m+n)的算法。 仔细想来,有如下三种方法求解。

    • 方法一: 先合并后求解,时间复杂度为O(m+n), 空间复杂度也为O(m+n)
    • 方法二: 不合并但使用计数器辅助求解,时间复杂度为O(m+n), 空间复杂度为O(1)
    • 方法三: 采用分治法求解,时间复杂度为O(log(m+n))

    方法一: 申请一个数组c[], 长度为m+n。将a[]和b[]归并排序到c[]中;然后求解其中位数。

     1 int get_median(int a[], size_t na, int b[], size_t nb, int *median)
     2 {
     3         int nc = na + nb;
     4 
     5         /* 1. allocate aux[na+nb] */
     6         int *c = (int *)malloc(nc * sizeof(int));
     7         if (c == NULL) /* error */
     8                 return -1;
     9 
    10         /* 2. merge a[] and b[] into c[] */
    11         int i = 0; /* walk list A : read  */
    12         int j = 0; /* walk list B : read  */
    13         int k = 0; /* walk list C : write */
    14 
    15         while (i < na && j < nb) {
    16                 if (a[i] < b[j])
    17                         c[k++] = a[i++];
    18                 else
    19                         c[k++] = b[j++];
    20         }
    21 
    22         while (i < na)
    23                 c[k++] = a[i++];
    24 
    25         while (j < nb)
    26                 c[k++] = b[j++];
    27 
    28         /* 3. get the median */
    29         *median = (nc % 2 == 0) ? (c[nc/2 - 1] + c[nc/2]) / 2 : c[nc/2];
    30 
    31         /* 4. free the aux[] */
    32         free(c);
    33 
    34         return 0;
    35 }

    方法二: 对方法一的空间复杂度进行改进,改进后的空间复杂度为O(1),但时间复杂度仍为O(m+n)。

     1 int get_median(int a[], size_t na, int b[], size_t nb)
     2 {
     3         int median = 0;
     4         int nc = na + nb;
     5 
     6         int prev = 0;
     7         int this = 0;
     8 
     9         int i = 0; /* walk list A : read */
    10         int j = 0; /* walk list B : read */
    11         int k = 0; /* walk list A u B */
    12         while (i < na && j < nb) {
    13                 if (a[i] < b[j])
    14                         this = a[i++];
    15                 else
    16                         this = b[j++];
    17 
    18                 if (k++ == nc / 2)
    19                         goto done;
    20 
    21                 prev = this;
    22         }
    23 
    24         while (i < na) {
    25                 this = a[i++];
    26 
    27                 if (k++ == nc / 2)
    28                         goto done;
    29 
    30                 prev = this;
    31         }
    32 
    33         while (j < nb) {
    34                 this = b[j++];
    35 
    36                 if (k++ == nc / 2)
    37                         goto done;
    38 
    39                 prev = this;
    40         }
    41 
    42 done:
    43         median = (nc % 2 != 0) ? this : (this + prev) / 2;
    44         return median;
    45 }

    方法三: 采用分治策略降低时间复杂度。

    。。。未完待续。。。

    参考资料:

  • 相关阅读:
    第十六章 Centos7下Docker安装GitLab
    第二十六章 Kubeadm方式搭建kubernetes高可用集群
    第二十五章 Kubernetes部署Promethus集群资源监控
    小程序遮罩层效果实现
    docker停止所有,删除容器命令
    sp欢迎页支持
    c#学习
    静态资源访问前缀
    webjar使用
    springboot静态资源配置原理
  • 原文地址:https://www.cnblogs.com/idorax/p/8067050.html
Copyright © 2011-2022 走看看