寻找两个已序数组中的第k大元素

1、问题描述

  给定两个数组,其大小分别为,假定它们都是已按照增序排序的数组,我们用尽可能快的方法去求两个数组合并后第大的元素,其中,。例如,对于数组。我们记第大的数为,则时,。这是因为排序之后的数组,第4大的数是4。我们针对这一个问题进行探讨。

2、算法一

  第一眼看到这个题的时候,我们能够很快地想出来最基本的一种解法:对数组进行合并,然后求出其第大的数,即找到答案。合并的过程,我们可以参考归并排序的合并子数组的过程,时间复杂度为。下面给出算法:

 
int findKthMaxNumOfArrays(int *a,int m,int *b,int n,int k)
{
int *p=a;
int *q=b;
int i=0;
int j=0;
int cur=0;
while(i<m&&j<n)
{
if(a[i]<b[j])
{
cur++;
if(cur==k) return a[i];
i++;
}
else
{
cur++;
if(cur==k) return b[j];
j++;
}
}
while(i<m)
{
cur++;
if(cur==k) return a[i];
i++;
}
while(j<n)
{
cur++;
if(cur==k) return b[j];
j++;
}
}

3、算法二

  实际上算法一的时间复杂度已经是线性的了。可是,是否存在更快的算法能够完成这项任务呢?答案是肯定的,时间复杂度可以缩短到时间内。在这种算法中,二分的思想十分重要。我们将数组分为两半,前一部分的大小为,后一部分为;数组同时分为这样两部分,第一部分的大小为,第二部分的大小为。如下图所示:

通过,我们将每个数组分为2部分,分别记为。假定,如果不是,我们只需要交换两个数组即可。接下来,我们看第大的数落在了哪个区间里面,令,这个实际上是包含了。如果时,则说明肯定不在里面,这是由于:中的所有数,而中的所有数与,而这部分数总共有个,说明是第个,若出现在中,则说明,与假设矛盾。我们可以得出该结论。因此,在判断之后,我们可以剔除数组部分,然后再在新数组中寻找;另外,如果,则说明肯定不在部分,这部分的证明同上一个证明相同,不再赘述。同样地,在判断之后,我们可以剔除数组部分,然后再在新数组中寻找。基于这样一种思想,我们每次迭代,都删除了其中一个数组中一半的元素,时间复杂度大约可认为是

  在实现的时候,我们需要特别注意边界条件,详细的代码如下:

int findKthMaxNumOfArrays(int *A, int m, int *B, int n, int k)
{
if(m == 0)return B[k-1];
if(n == 0)return A[k-1];
int i = m>>1, j = n>>1, *p, *q, t;
if(A[i] <= B[j])p = A, q = B;
else p = B, q = A, swap(i, j), swap(m, n);
t = i + j + 1;
if(t >= k)return func(p, m, q, j, k);
else if(t < k)return func(p+i+1, m-i-1, q, n, k-i-1);
}

4、扩展问题

  通过算法二,我们很容易地解决一个类似的问题:求两个已序数组,的中位数。所谓的中位数,对于一个有个元素的已序数组,如果是奇数,则中位数是第个元素的值;如果是偶数,则它的中位数是第与第数的平均值。对于为奇数,则利用算法二求第个元素的值即可,对于为偶数,利用算法二求第个与第个元素的值,求其平均值即可。

  对于这个问题,在LeetCode中有另外一种解法,但是阅读后发现其需要处理的个别case太多,相比而言没有本文所介绍的算法简洁。如果想要了解,给出链接:http://leetcode.com/2011/03/median-of-two-sorted-arrays.html

作者:Chenny Chen 
出处:http://www.cnblogs.com/XjChenny/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

寻找两个已序数组中的第k大元素的更多相关文章

  1. 【算法剖析】寻找两个已序数组中的第k大元素

    1.问题描述 给定两个数组A与B,其大小分别为m.n,假定它们都是已按照增序排序的数组,我们用尽可能快的方法去求两个数组合并后第k大的元素,其中,1\le k\le(m+n).例如,对于数组A=[1, ...

  2. leetcode-4. 寻找两个正序数组的中位数

    leetcode-4. 寻找两个正序数组的中位数. 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2. 请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(l ...

  3. 17082 两个有序数序列中找第k小

    17082 两个有序数序列中找第k小 时间限制:1000MS  内存限制:65535K 提交次数:0 通过次数:0 题型: 编程题   语言: 无限制 Description 已知两个已经排好序(非减 ...

  4. 17082 两个有序数序列中找第k小(优先做)

    17082 两个有序数序列中找第k小(优先做) 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC Description 已 ...

  5. 17082 两个有序数序列中找第k小(优先做) O(logn)

    17082 两个有序数序列中找第k小(优先做) 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC Description 已 ...

  6. 如何寻找无序数组中的第K大元素?

    如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...

  7. Leetcode 703. 数据流中的第K大元素

    1.题目要求 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器, ...

  8. Java实现 LeetCode 703 数据流中的第K大元素(先序队列)

    703. 数据流中的第K大元素 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组n ...

  9. 微软面试题: LeetCode 4. 寻找两个正序数组的中位数 hard 出现次数:3

    题目描述: 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的中位数. 进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决 ...

随机推荐

  1. EF结合SqlBulkCopy

    EF结合SqlBulkCopy在项目中的使用 这是我第一次写博客,由于水平有限,写不出什么好东西,还望见谅. 我现在参与的这个项目采用的是EF框架,方便了数据库的访问.但在实际中,发现项目中导入市县E ...

  2. 网页动态切换母版页(MasterPage)

    原文:网页动态切换母版页(MasterPage) 是否可以变更网页的母版页(MasterPage)呢?某.aspx在创建时,已经附加入某一母版页(MasterPage)了,现需要.aspx动态变更母版 ...

  3. Asp.Net MVC5入门学习系列⑥

    原文:Asp.Net MVC5入门学习系列⑥ 接着上次的篇幅,我们这篇手动来写一个查询的流程代码! 搜索/查询 流程功能的实现 那现在要做搜索(查询)功能我们第一步应该做什么呢!第一次是不是我们应该去 ...

  4. jQuery实现表格行的动态增加与删除

    删除之前删除2行后: 1<script> 8 $(document).ready(function(){ 9 //<tr/>居中 10 $("#tab tr" ...

  5. 用CQRS+ES实现DDD

    用CQRS+ES实现DDD 这篇文章应该算是对前三篇的一个补充,在写之前说个题外话,有园友评论这是在用三层架构在写DDD,我的个人理解DDD是一种设计思想,跟具体用什么架构应该没有什么关系,DDD也需 ...

  6. 项目笔记---CSharp图片处理

    原文:项目笔记---CSharp图片处理 项目笔记---CSharp图片处理 最近由于项目上需要对图片进行二值化处理,就学习了相关的图片处理上的知识,从开始的二值化的意义到动态阀值检测二值化等等,并用 ...

  7. Python开发环境Wing IDE 5.0测试第八版发布

    Wing IDE是著名的Python开发工具,是Wingware公司的主要产品.从1999年起,Wingware公司便开始专注于Python开发设计.Wing IDE在十几年的发展中,不管完善.其强大 ...

  8. How do I create an IIS application and application pool using InnoSetup script

    Create an IIS application. Create a new IIS application pool and set it's .NET version to 4. Set the ...

  9. 【SSRS】入门篇(三) -- 为报表定义数据集

    原文:[SSRS]入门篇(三) -- 为报表定义数据集 通过前两篇文件 [SSRS]入门篇(一) -- 创建SSRS项目 和 [SSRS]入门篇(二) -- 建立数据源 后, 我们建立了一个SSRS项 ...

  10. 【转】删除修改Eclipse里的SVN账户

    转自http://msongli.iteye.com/blog/1186648 引自: http://wanghongxu.iteye.com/blog/539806 http://jxdwuao.i ...