美文网首页
两个有序数组的第K大的数,看不会包打!

两个有序数组的第K大的数,看不会包打!

作者: Top2_头秃 | 来源:发表于2019-04-21 20:06 被阅读0次

要求时间复杂度是O(log(m+n)),一看时间复杂度是log,那肯定是采用了二分(分治)的方法才能达到log的效果~~~

废话不多说,直接开干,顺带说一下,c语言是世界上最好的语言~~~~~~
设有如下两个有序数组:

a[3] = {1,2,3}; 
b[6] = {2,3,4,5,6,7}

以下分析步骤

  1. 求第k大的数,我们设这k个数,包含在数组a中的有p个,包含b中的有q个,则有p+q=k; a数组的起始索引astart = 0,b数组的起始索引bstart=0
  2. 那么怎么确定p呢,我们设p = min(k/2,m),这里我们假设m是比较短的那个数组的长度,取p= k/2和m的较小者,保证数组不越界。则q=k-p
  3. 以 a b 为例 m = 3,n = 6; 假如要求中位数(k=4);p=min(k/2,m)= 2,q= k-p=2
  4. 如果 a[astart+p-1] < b[bstart+q-1]; 我们就可以把a数组中包括索引p在内的比较小的数都抛弃,形成一个新的数组a' 与 b 再来一次上述过程,如果a[astart+p-1] > b[bstart+q-1]; 就抛弃b中的较小的数 形成一个新的数组b',与a再来一次;如果相等 那这个数就是要找的中位数

️:循环的结束条件是 如果较短的数组长度为0(比如a数组)了,则返回b[bstart+k-1]; 如果k==1了 则返回 a[astart]与b[bstart]中的较小者

代码如下

float findTheKBigNum(int *a, int *b,int aStart, int bStart, int aLen, int bLen, int k) {
    // 这里使用较短的数组作为a,保证不越界
    if (aLen > bLen) {
        findTheKBigNum(b, a, bStart ,aStart, bLen, aLen, k);
    }
    if (aLen == 0) {
        return b[bStart+k-1];
    }
    if (k == 1) {
        return a[aStart] < b[bStart] ? a[aStart] : b[bStart];
    }
    
    int p1 = k/2 < aLen ? k/2:aLen;
    int p2 = k-p1;
    if (a[aStart+p1-1] < b[bStart+p2-1]) {
        return findTheKBigNum(a, b, aStart+p1, bStart, aLen-p1, bLen, k-p1);
    } else if (a[aStart+p1-1] > b[bStart+p2-1]) {
        return findTheKBigNum(a, b, aStart, bStart+p2, aLen, bLen-p2, k-p2);
    } else {
        return a[aStart+p1-1];
    }
}

查找中位数函数

float mediumNum(int *a, int *b, int m, int n) {
    int k = (m+n)/2;
    if ((m+n)%2 == 0) {
      //  如果合并后的数组长度是偶数,中位数为第k大和第k+1大之和的一半
        return (findTheKBigNum(a, b, 0, 0, m, n, k)+findTheKBigNum(a, b, 0, 0, m, n, k+1))/2;
    } else {
        return findTheKBigNum(a, b, 0, 0, m, n, k+1);
    }
}

相关文章

  • 两个有序数组的第K大的数,看不会包打!

    要求时间复杂度是O(log(m+n)),一看时间复杂度是log,那肯定是采用了二分(分治)的方法才能达到log的效...

  • LeetCode 215. Kth Largest Elemen

    @(LeetCode) 问题描述 找出数组中第 k 个最大的数。注意是数组排序后第 k 大的数,而不是去重后的第 ...

  • Leetcode.215.Kth Largest Element

    题目 给定一个数组, 输出第k大的数. 思路 进行从大到小排序, 第k-1即为第k大的数. 总结 掌握快速排序.

  • 4. Median of Two Sorted Arrays

    两个有序数组的中位数,相当于寻找两个数组第k大的值,利用二分法进行查找,确定之后改变k的值与起始索引。 合并两个有...

  • 2018-09-27 215. Kth Largest Elem

    题意:给你一个无序数组,返回该数组第K大的数(重复的两个数算两个)。解题思路:使用优先队列priority_que...

  • leetcode-0004

    题目: 4. 寻找两个有序数组的中位数 关键词:排序 折半查找 思路: 查找第k个数,每次查找二个数组的第k/2位...

  • Lua 快速排序

    快排 在一个数组中快速找出第K大的数

  • 小范围排序练习题

    题目 已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数...

  • 近似有序数组排序

    题目 已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数...

  • 5. 第k大元素

    题目:在数组中找到第k大的元素(JAVA) 审题:输入:目标数n 输出:数组int[] nums 分析:...

网友评论

      本文标题:两个有序数组的第K大的数,看不会包打!

      本文链接:https://www.haomeiwen.com/subject/krajgqtx.html