zoukankan      html  css  js  c++  java
  • 计算两个有序数组的第K大数(转)

    • 传统解法,最直观的解法是O(m+n)。直接merge两个数组,然后求第K大的数字。

    • 如果想要时间复杂度将为O(log(m+n))。我们可以考虑从K入手。如果我们每次能够删除一个一定在第K个元素之前的元素,那么我们需要进行K次,但是如果每次我们都删除一半呢?由于两个数组都是有序的,我们应该充分利用这个信息。

      • 假设A B 两数组的元素都大于K/2,我们将A B两数组的第K/2个元素进行比较。比较的结果有三种情况。
        • A[K/2] == B[K/2]
        • A[K/2] > B[K/2]
        • A[K/2] <= B[K/2]
      • 如果 A[K/2] < B[K/2] 意味着 A[0] 到 A[K/2] 肯定在A∪B的前k个元素中。因此我们可以放心删除A数组的这个k/2个元素。同理A[K/2] > B[K/2]。
      • 如果 A[K/2] == B[K/2] 说明已经找到了第K个元素,直接返回A[K/2]或者B[K/2]。
    • 代码如下

       1 int find_kth(int A[],int m, int B[], int n, int k){
       2     if(m > n )
       3         return find_kth(B, n, A, m, k);
       4     if( m == 0)
       5         return B[k-1];
       6     if( k == 1)
       7         return min(A[0], B[0]);
       8 
       9     int ia = min(k /2, m);
      10     int ib = k -ia;
      11     if( A[ia-1] < B[ib -1]){
      12         return find_kth(A +ia, m -ia, B, n, k -ia);
      13     }else if( A[ia-1] > B[ib-1]){
      14         return find_kth(A, m, B +ib, n -ib, k -ib);
      15     }else
      16         return A[ia-1];
      17 }

      说明

      • 注意其中的递归终止条件。
      • 将求第K大元素的问题划分成为子问题,不断的对问题进行缩小,采取递归的方式求解。
      • 此问题可以进行拓展,比如求两有序数组的中位数。

    转自:http://www.cnblogs.com/swanspouse/p/5285015.html

  • 相关阅读:
    IE 中的 button type默认值问题
    linux中的&&和&,|和||
    scp 上传 下载 文件
    git 撤销,放弃本地修改
    git branch 新建,推送与删除
    git tags 管理
    CentOS7下Firewall常用命令
    git 忽略文件,不提交文件 清空缓存
    mysql 常用命令
    优秀的测试人员简历是什么样子的?
  • 原文地址:https://www.cnblogs.com/zl1991/p/7121770.html
Copyright © 2011-2022 走看看