博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
两个有序数组中找中位数或者第K大的元素
阅读量:4649 次
发布时间:2019-06-09

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

RT,在两个有序数组中找中位数或者第K大的元素.

假设两个数组为A, B长度分别为m,n.分别是递增顺序。

可以采用的算法有很多:

首先想到的是类似MergeSort的方式,合并的同时找第K大元素,这个基本没难度,复杂度O(m + n)。

不过此算法并不是最优,还有Log级别复杂度的算法,此算法其实很简单,远没有很多网站的代码那么玄乎,以下一一道来:

首先明白几个前提:

1.如果是求中位数,(m + n)是奇数还是偶数对结果是很有影响的,具体的如果(m + n)是奇数,中位数唯一,如果是偶数就有两个中位数,怎么取舍就看要求了。

2.如果找到的第k大数(中位数类似)是 X ,如果X排在A中的 第Ax位置,X排序在B中的Bx位置,那么(Ax + Bx - 1) == k 是恒成立的。

明白了2中的前提后,我们就可以得到一个算法,在A数组中枚举X,加入在A中是第Ax个,那么可以反推B中第 (k + 1 - Ax)个以及相邻元素和X的大小关系就可以得到一个Log级别复杂度的算法:

简单点我们可以这么想:

1)先假设第k大数在A中,我们首先从A中第(m/(m + n)) * (k - 1)个元素开始检查其是否是第k个元素,假设其值为A1,然后看B中第(k + 1 - (m/(m + n)) * (k - 1)个元素(B1)和A1是否相等,或者 大于B中第(k + 1 - (m/(m + n)) * (k - 1))个元素,小于B中第(k + 1 - (m/(m + n)) * (k - 1))+ 1个元素。满足及可以知道A1即为所求。如果两个条件都不满足,请看2.

2)如果两个条件都不满足,那么需要判断第k个元素是处于 A1的左边还是右边,这个就是典型的分治思想。具体的来说:

             if A1 > B1  那么k可以排除肯定不在A[0, (m/(m + n)) * (k - 1)]以及B[(k + 1 - (m/(m + n)) * (k - 1))+ 1, n]中

             if A1< B1  那么k可以排除肯定不在A[ (m/(m + n)) * (k - 1), m]以及B[0, (k + 1 - (m/(m + n)) * (k - 1))]中.

             注意下临界条件(corner condition may not stastify, but the method is right)

第K个元素有可能在B中,同理可以假设在B中,然后再搜索一遍就可以查到。复杂度 log(m)+ log(n)

当然也可以两个数组一起找,总体代码如下:

1     int kthsmallest(int *a,int m,int *b,int n,int k) { 2         if (m == 0) { 3             return b[k - 1]; 4         } 5         if (n == 0) { 6             return a[k - 1]; 7         } 8         if (k == 1) { 9             return (a[0] < b[0])?a[0]:b[0];10         }11         if (k == m + n) {12             return (a[m - 1] > b[n - 1])?a[m - 1]:b[n - 1];13         }14         int i = ((double) m) / (m + n) * (k - 1);15         int j = k - 1 - i;16         if (j >= n) {17             j = n - 1;18             i = k - n;19         }20         if (((i == 0) || (a[i - 1] <= b[j])) && (b[j] <= a[i])) {21             return b[j];22         }23         if (((j == 0) || (b[j - 1] <= a[i])) && (a[i] <= b[j])) {24             return a[i];25         }26         if (a[i] <= b[j]) {27             return kthsmallest(a + i + 1, m - i - 1, b, j, k - i - 1);28         } else {29             return kthsmallest(a, i, b + j + 1, n - j - 1, k - j - 1);30         }31 32     }

 

 

转载于:https://www.cnblogs.com/davidluo/articles/k-smallest-element-of-two-sorted-array.html

你可能感兴趣的文章
.NET中的三种Timer的区别和用法
查看>>
python第三方包安装方法(两种方法)
查看>>
MySQL 索引知识整理(创建高性能的索引)
查看>>
C++ 头文件
查看>>
ZOJ 1008 Gnome Tetravex(DFS)
查看>>
Mysql基础知识:操作数据库
查看>>
mysql 数据库远程访问设置方法
查看>>
Far manager界面混乱问题解决
查看>>
java读取xml文件
查看>>
Go数组和切片定义和初始化
查看>>
用javascript将数据导入Excel
查看>>
novoton-timer使用
查看>>
[Office]PPT 2013如何设置图片为半透明?
查看>>
原生js实现浏览器全屏和退出全屏
查看>>
选择排序(c++)
查看>>
特殊文件(下)
查看>>
ubuntu通过vmware与访问宿主的文件
查看>>
mysql 5.7 二进制安装方法
查看>>
244. Shortest Word Distance II
查看>>
385. Mini Parser
查看>>