• 两个有序数组的中位数求解方法


    有两个已经升序排列的数组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 }

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

    。。。未完待续。。。

    参考资料:

  • 相关阅读:
    eclipse如何正确部署tomcat7
    调用awk的三种方式
    jupyter的简单操作
    编程语言简介
    2019.9.6作业
    计算机的基本组成
    9.2作业
    CPP 栈 示例
    关于使用栈将一般运算式翻译为后缀表达式并实现三级运算的方法及实例(cpp版)
    深度遍历破解数独游戏
  • 原文地址:https://www.cnblogs.com/idorax/p/8067050.html
Copyright © 2020-2023  润新知