两个有序数组中查找第K大数

题目:两个数组A、B,长度分别为m、n,即A(m)、B(n),分别是递增数组。求第K大的数字。

 

方法一:

简单的办法,使用Merge Sort,首先将两个数组合并,然后在枚举查找。这个算法的时间复杂度是O(m+n)、空间复杂度也是O(M+n)。

这个方法其实没有考虑到有第K大数为两个相同数字的情况。

 

方法二:

这里需要两个前提条件,

1、如果K是中位数,则(M+n)是奇数还是偶数是有关系的。如果是奇数,那么中位数唯一,如果是偶数就有两个中位数,可以随便取一个。

2、如果找到的第K大数是x,假如在A的位置是A(x),在B中的位置是B(x),则Ax+Bx-1=k是成立的。

 

接下来是具体实现逻辑:

1、首先假设K大数在A数组中,首先检查 (m/(m+n))*(k-1),假设其值为A1。然后检查B中(k+1-(n/(m+n))*(k-1))假设为B1,检查A1、B1是否相等,或者大于B中的第(k+1-(n/(m+n))*(k-1)),并且小于(k+1-(n/(m+n))*(k-1))+1个元素。满足条件就可以知道A1就是所求,否则看条件2。

2、如果两个条件都不满足,那么需要判断第K个元素是位于A1左边还是右边。

 

如果A1>B1,那么K肯定不在A[0, (m/(m + n)) * (k - 1)]以及B[(k + 1 - (m/(m + n)) * (k - 1))+ 1, n]中;

如果A1<B1,那么K肯定不在A[ (m/(m + n)) * (k - 1), m]以及B[0, (k + 1 - (m/(m + n)) * (k - 1))]中。

 

第K个元素有可能在B中,同理可以假设在B中,再进行一次搜索。复杂度为log(m)+log(n)。

 

具体代码如下:

int kthsmallest(int *a,int m,int *b,int n,int k) {

        if (m == 0) {

            return b[k - 1];

        }

        if (n == 0) {

            return a[k - 1];

        }

        if (k == 1) {

            return (a[0] < b[0])?a[0]:b[0];

        }

        if (k == m + n) {

            return (a[m - 1] > b[n - 1])?a[m - 1]:b[n - 1];

        }

        int i = ((double) m) / (m + n) * (k - 1);

        int j = k - 1 - i;

        if (j >= n) {

            j = n - 1;

            i = k - n;

        }

        if (((i == 0) || (a[i - 1] <= b[j])) && (b[j] <= a[i])) {

            return b[j];

        }

        if (((j == 0) || (b[j - 1] <= a[i])) && (a[i] <= b[j])) {

            return a[i];

        }

        if (a[i] <= b[j]) {

            return kthsmallest(a + i + 1, m - i - 1, b, j, k - i - 1);

        } else {

            return kthsmallest(a, i, b + j + 1, n - j - 1, k - j - 1);

        }

 

    }

 

 

方法三:

当然也可以在方法一的基础上,采用一些二分的办法进行优化,但是这种算法

 

 

参考资料:

1、http://www.cnblogs.com/davidluo/articles/k-smallest-element-of-two-sorted-array.html

2、http://blog.csdn.net/realxie/article/details/8078043

3、http://blog.csdn.net/shifuwawa/article/details/6121573

4、http://eriol.iteye.com/blog/1172098

时间: 2024-08-01 09:21:03

两个有序数组中查找第K大数的相关文章

有序数组中找中位数

原文:Median of two sorted arrays 题目:两个有序数组A和B,大小都是n,寻找这两个数组合并后的中位数.时间复杂度为O(logn). 中位数:如果数组的个数是奇数,那么中位数的值就是有序时处于中间的数:如果数组个数是偶数的,那么就是有序时中间两个数的平均值. 方法一:合并时计数 使用Merge Sort时的Merge操作,比较两个数组时候计数,当计数达到n时,就可以得到中位数,在归并的数组中,中位数为下标n-1和n的两个数的平均值. 时间复杂度O(n). #includ

JavaScript使用二分查找算法在数组中查找数据的方法_javascript技巧

本文实例讲述了JavaScript使用二分查找算法在数组中查找数据的方法.分享给大家供大家参考.具体分析如下: 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一

php在数组中查找指定值的方法_php技巧

本文实例讲述了php在数组中查找指定值的方法.分享给大家供大家参考.具体如下: php中有两个函数可以判断数组中是否包含指定的值,分别是:array_search($value, $array)和in_array($value, $array),array_search可以找出指定的值在数组中出现的位置,in_array函数只判断数组中是否存在指定的值,返回bool值 <?php $array = array("Perl", "PHP", "Java

C++二分法在数组中查找关键字的方法_C 语言

本文实例讲述了C++二分法在数组中查找关键字的方法.分享给大家供大家参考.具体如下: /* 此程序演示了二分法查找算法(针对按从小到大排列的数组)的实现. */ #include <iostream> using namespace std; /* 功能: 实现数组的二分法查找(只算法只适合按从小到大排列的数组) 返回值:关键字在数组中的下标, 返回-1表示未找到 a[]: 要搜索的数组 len: 数组元素个数 key: 要查找的关键字 */ int binSearch(int a[], in

php实现在多维数组中查找特定value的方法_php技巧

本文实例讲述了php实现在多维数组中查找特定value的方法.分享给大家供大家参考.具体如下: 最近做项目,需要从多维数组中查找是否含有特定的key和其对应特定的value,并清除该条数据,比如: $arr = array( //为了看的方便,数组表达形式不对 0=>array(id =>1,name =>"li") 1=>array(id =>2,name =>"na") 2=>array(id =>3,name =

C语言OJ项目参考(1045)插入有序数组中

1045:插入有序数组中 Description 已有一个已排好的9个元素的数组,今输入一个数要求按原来排序的规律将它插入数组中. Input 第一行,原始数列.第二行,需要插入的数字. Output 排序后的数列 Sample Input 1 7 8 17 23 24 59 62 101 50 Sample Output 1 7 8 17 23 24 50 59 62 101 参考解答: #include <stdio.h> int main() { int a[10],i,n; for(i

采用归并排序算法查找两个字符串数组中的不同数据

  现在项目中有需求比较两个字符串数组,找出其中不同的部分,并保存到本地txt.实现方式每个人都有自己的思路,这里提供一种通过归并排序实现的方式供大家参考.   基本思路是数组A和数组B对比,使用数组a来保存数组A中比数组B中多的元素(即在A中存在,B中不存在的元素),b来保存数据B中比数组A中多的元素(即B中存在,A中不存在的元素).开始需要分别调用Sort()函数对A.B数组进行排序,然后使用CompareTo从两个数组中第一个数组进行比较,当A.0(A中第一个元素)>B.0时A.Compa

无序整数数组中找第k大的数

方法一:基于快排 1 /* 2 基于区间快排的第K小算法 ,输出a[k-1]即可,O(n*logn):每次只对后半部分递归便可把复杂度降到O(n) 3 主要思路是每次随机在数组中选取一个元素p,利用这个元素将数组分成两部分,比p小的元素在分好的数组左边,p和比p大的元素在数组右边, 4 根据k值选择在数组左半或者右半部分继续递归执行查找. 5 */ 6 #include <iostream> 7 #include <cstring> 8 #include <vector>

JavaScript实现在数组中查找不同顺序排列的字符串

  需求描述:从一组数组中找出一组按不同顺序排列的字符串的数组元素.假如有这样一个数组: 代码如下: [ 'abcd', 'hello', 'bdca', 'olleh', 'cadb', 'nba', 'abn', 'abc' ] 需要找出的结果是: 代码如下: [ 'abcd', 'bdca', 'cadb' ] 那么这里的关键点是判断一组字符串是否是否只是字符的顺序不同,只要解决整个关键点其他都好办了. 方法1: 代码如下: var stringClassify = function( a