博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有序数组中找中位数
阅读量:6162 次
发布时间:2019-06-21

本文共 8065 字,大约阅读时间需要 26 分钟。

原文:

题目:两个有序数组A和B,大小都是n,寻找这两个数组合并后的中位数。时间复杂度为O(logn)。

中位数:如果数组的个数是奇数,那么中位数的值就是有序时处于中间的数;如果数组个数是偶数的,那么就是有序时中间两个数的平均值。

方法一:合并时计数

使用Merge Sort时的Merge操作,比较两个数组时候计数,当计数达到n时,就可以得到中位数,在归并的数组中,中位数为下标n-1和n的两个数的平均值。

时间复杂度O(n)。

#include 
/* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int i = 0; /* Current index of i/p array ar1[] */ int j = 0; /* Current index of i/p array ar2[] */ int count; int m1 = -1, m2 = -1; /* Since there are 2n elements, median will be average of elements at index n-1 and n in the array obtained after merging ar1 and ar2 */ for (count = 0; count <= n; count++) { /*Below is to handle case where all elements of ar1[] are smaller than smallest(or first) element of ar2[]*/ if (i == n) { m1 = m2; m2 = ar2[0]; break; } /*Below is to handle case where all elements of ar2[] are smaller than smallest(or first) element of ar1[]*/ else if (j == n) { m1 = m2; m2 = ar1[0]; break; } if (ar1[i] < ar2[j]) { m1 = m2; /* Store the prev median */ m2 = ar1[i]; i++; } else { m1 = m2; /* Store the prev median */ m2 = ar2[j]; j++; } } return (m1 + m2)/2; } /* Driver program to test above function */ int main() { int ar1[] = {
1, 12, 15, 26, 38}; int ar2[] = {
2, 13, 17, 30, 45}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); return 0; }

方法二:比较两个数组的中位数

ar1[]和ar2[]为输入的数组

算法过程:

1.得到数组ar1和ar2的中位数m1和m2

2.如果m1==m2,则完成,返回m1或者m2

3.如果m1>m2,则中位数在下面两个子数组中

a) From first element of ar1 to m1 (ar1[0...|_n/2_|])

b) From m2 to last element of ar2 (ar2[|_n/2_|...n-1])

4.如果m1<m2,则中位数在下面两个子数组中

a) From m1 to last element of ar1 (ar1[|_n/2_|...n-1])

b) From first element of ar2 to m2 (ar2[0...|_n/2_|])

5.重复上面的过程,直到两个子数组的大小都变成2

6.如果两个子数组的大小都变成2,使用下面的式子得到中位数:Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2

时间复杂度:O(logn)。

#include 
/* Utility functions */ int max(int x, int y) { return x > y? x : y; } int min(int x, int y) { return x > y? y : x; } /* Function to get median of a sorted array */ int median(int arr[], int n) { if (n%2 == 0) return (arr[n/2] + arr[n/2-1])/2; else return arr[n/2]; } /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int m1; /* For median of ar1 */ int m2; /* For median of ar2 */ /* return -1 for invalid input */ if (n <= 0) return -1; if (n == 1) return (ar1[0] + ar2[0])/2; if (n == 2) return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2; m1 = median(ar1, n); /* get the median of the first array */ m2 = median(ar2, n); /* get the median of the second array */ /* If medians are equal then return either m1 or m2 */ if (m1 == m2) return m1; /* if m1 < m2 then median must exist in ar1[m1....] and ar2[....m2] */ if (m1 < m2) { if (n % 2 == 0) return getMedian(ar1 + n/2 - 1, ar2, n - n/2 +1); else return getMedian(ar1 + n/2, ar2, n - n/2); } /* if m1 > m2 then median must exist in ar1[....m1] and ar2[m2...] */ else { if (n % 2 == 0) return getMedian(ar2 + n/2 - 1, ar1, n - n/2 + 1); else return getMedian(ar2 + n/2, ar1, n - n/2); } } /* Driver program to test above function */ int main() { int ar1[] = {
1, 2, 3, 6}; int ar2[] = {
4, 6, 8, 10}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); return 0; }

方法三:通过二分查找法来找中位数

基本思想是:假设ar1[i]是合并后的中位数,那么ar1[i]大于ar1[]中前i-1个数,且大于ar2[]中前j=n-i-1个数。通过ar1[i]和ar2[j]、ar2[j+1]两个数的比较,在ar1[i]的左边或者ar1[i]右边继续进行二分查找。对于两个数组 ar1[] 和ar2[], 先在 ar1[] 中做二分查找。如果在ar1[]中没找到中位数, 继续在ar2[]中查找。

算法流程:

1) 得到数组ar1[]最中间的数,假设下标为i.
2) 计算对应在数组ar2[]的下标j,j = n-i-1 
3) 如果 ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1],那么 ar1[i] 和 ar2[j] 就是两个中间元素,返回ar2[j] 和 ar1[i] 的平均值
4) 如果 ar1[i] 大于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的左部分做二分查找(i.e., arr[left ... i-1])
5) 如果 ar1[i] 小于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的右部分做二分查找(i.e., arr[i+1....right])
6) 如果到达数组ar1[]的边界(left or right),则在数组ar2[]中做二分查找

时间复杂度:O(logn)。

#include 
/* A recursive function to get the median of ar1[] and ar2[] using binary search */ int getMedianRec(int ar1[], int ar2[], int left, int right, int n) { int i, j; /* We have reached at the end (left or right) of ar1[] */ if(left > right) return getMedianRec(ar2, ar1, 0, n-1, n); i = (left + right)/2; j = n - i - 1; /* Index of ar2[] */ /* Recursion terminates here.*/ if (ar1[i] > ar2[j] && (j == n-1 || ar1[i] <= ar2[j+1])) { /*ar1[i] is decided as median 2, now select the median 1 (element just before ar1[i] in merged array) to get the average of both*/ if (ar2[j] > ar1[i-1] || i == 0) return (ar1[i] + ar2[j])/2; else return (ar1[i] + ar1[i-1])/2; } /*Search in left half of ar1[]*/ else if (ar1[i] > ar2[j] && j != n-1 && ar1[i] > ar2[j+1]) return getMedianRec(ar1, ar2, left, i-1, n); /*Search in right half of ar1[]*/ else /* ar1[i] is smaller than both ar2[j] and ar2[j+1]*/ return getMedianRec(ar1, ar2, i+1, right, n); } /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { // If all elements of array 1 are smaller then // median is average of last element of ar1 and first element of ar2 if (ar1[n-1] < ar2[0]) return (ar1[n-1]+ar2[0])/2; // If all elements of array 1 are smaller then // median is average of first element of ar1 and // last element of ar2 if (ar2[n-1] < ar1[0]) return (ar2[n-1]+ar1[0])/2; return getMedianRec(ar1, ar2, 0, n-1, n); } /* Driver program to test above function */ int main() { int ar1[] = {
1, 12, 15, 26, 38}; int ar2[] = {
2, 13, 17, 30, 45}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); return 0; }

原文地址:

 

作者:
出处:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/archive/2012/09/13/2684054.html
你可能感兴趣的文章
Win7+Ubuntu11
查看>>
请问华为三层交换机里面的那个从IP是个什么意思? -
查看>>
kFeedback开源啦
查看>>
大数据传输,文件传输的专业解决方案!
查看>>
阿里云专家穆轩的《杭州九年程序员之“修炼”手册》
查看>>
JQuery:deferred对象的方法
查看>>
eyoucms问答 百度权重是什么
查看>>
win10中遇到qq视频时摄像头打不开没反应的解决方法
查看>>
介绍自己的一个Android插桩热修复框架项目QuickPatch
查看>>
关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
查看>>
Solr Facet 查询
查看>>
C++类的继承一
查看>>
数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...
查看>>
巧用VMware Workstation的clone来制作虚拟机模板
查看>>
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
查看>>
HP DL380G4服务器前面板指示灯的含义
查看>>
数据结构_树结构
查看>>
常用URL地址
查看>>
每天一个linux命令(19):find 命令概览
查看>>
MySQL kill操作
查看>>