专栏首页小狼的世界两个有序数组中查找第K大数

两个有序数组中查找第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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CSS3 Transition介绍

    CSS3提供了一种全新的方式来定义CSS属性改变时的过渡效果,通常在:hover、:focus的条件下触发。过去,为了实现这种平滑的过渡效果,我们需要借助于Fl...

    大江小浪
  • 使用PHP的正则抓取页面中的网址

    最近有一个任务,从页面中抓取页面中所有的链接,当然使用PHP正则表达式是最方便的办法。要写出正则表达式,就要先总结出模式,那么页面中的链接会有几种形式呢?

    大江小浪
  • Docker 概述

    Docker 是一个应用程序开发、部署、运行的平台,使用 go 语言开发。相较于传统的主机虚拟化,Docker 提供了轻量级的应用隔离方案,并且为我们提供了应用...

    大江小浪
  • Golang Leetcode 202. Happy Number.go

    版权声明:原创勿转 https://blog.csdn.net/anakinsun/article/details/89012332

    anakinsun
  • python: int函数

    JNingWei
  • Leetcode Golang 120. Triangle.go

    版权声明:原创勿转 https://blog.csdn.net/anakinsun/article/details/88965777

    anakinsun
  • nginx limit配置参数解读

    解析一下ngx_http_core_module、ngx_http_limit_conn_module以及ngx_http_limit_req_module中的...

    拓荒者
  • 当输入流和输出流同时作用一个文件

    当输入流和输出流同时作用一个文件会发生什么 以前试过:当输入流或输出流作用在一个文件上,而且流没有关闭的话,这时候我想删除这个文件是失败的,会提示文件被占用...

    用户1174983
  • [Python程序]使用Python批量移动过期文件

    bsbforever
  • Dynamic Programming - 120. Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you ma...

    用户5705150

扫码关注云+社区

领取腾讯云代金券