两个有序数组的中位数c语言,两个有序数组的第K大的数,看不会包打!

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

废话不多说,直接开干,顺带说一下,c语言是世界上最好的语言~~~~~~

设有如下两个有序数组:

a[3] = {1,2,3};

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

以下分析步骤

求第k大的数,我们设这k个数,包含在数组a中的有p个,包含b中的有q个,则有p+q=k; a数组的起始索引astart = 0,b数组的起始索引bstart=0

那么怎么确定p呢,我们设p = min(k/2,m),这里我们假设m是比较短的那个数组的长度,取p= k/2和m的较小者,保证数组不越界。则q=k-p

以 a b 为例 m = 3,n = 6; 假如要求中位数(k=4);p=min(k/2,m)= 2,q= k-p=2

如果 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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值