LintCode: Median of two Sorted Arrays

简介:

求第k个值

1.归并排序

归并到第k个值为止

时间复杂度:O(k)

复制代码
 1 class Solution {
 2 public:
 3     // merge-sort to find K-th value
 4     double helper(vector<int> A, vector<int> B, int lenA, int lenB, int k) {
 5         int i = 0, j = 0;
 6         while ((i < lenA) && (j < lenB)) {
 7             k--;
 8             if (A[i] < B[j]) {
 9                 if (0 == k) {
10                     return A[i];
11                 }
12                 ++i;
13             } else if (0 == k) {
14                 return B[j];
15             } else {
16                 ++j;
17             }
18         }
19         return (i >= lenA)?B[j + k - 1]:A[i + k - 1];
20     }
21     /**
22      * @param A: An integer array.
23      * @param B: An integer array.
24      * @return: a double whose format is *.5 or *.0
25      */
26     double findMedianSortedArrays(vector<int> A, vector<int> B) {
27         // write your code here
28         int m = A.size();
29         int n = B.size();
30         return ((m + n) & 1)?
31         (helper(A, B, m, n, (m + n + 1)>>1)):
32         (((helper(A, B, m, n, ((m + n)>>1) + 1))+(helper(A, B, m, n, (m + n)>>1))) * .5);
33     }
34 };
复制代码

 

2. 分治法

利用归并的思想,从a和b中一共取k个数

假设len(a)<len(b)

从a中取pa = min(k/2, len(a))个元素;

从b中取pb = k-pa个元素;

如果a[pa - 1]<b[pb - 1],则归并排序时先归并a[pa - 1],说明a数组的数取“少”了,不够用

  a到终点后,只用b的数凑足了k个,这说明总的第k大的值不会出现在a[0...pa-1]里边,所以我们扔掉前pa个数

  对于b数组,说明总的第k大的数不会出现在b[pb...lenB]里边,pb后边的数就没用了

如果a[pa - 1]>=b[pb - 1],是对称情况

  归并排序时,会先归并b[pb - 1],说明b数组的数取“少”了,不够用

  b到终点后,只用a的数凑足了k个,这说明总的第k大的值不会出现在b[0...pb-1]里边,所以我们扔掉前pb个数

  对于a数组,说明第k大的数不会出现在a[pa...lenA]里边,pa的后边就没用了

总结:扔掉较小数组的前一部分,扔掉较大数组的后一部分

复杂度分析:O(logK), K每次几乎减少一半

复制代码
 1 class Solution {
 2 public:
 3     // merge-sort to find K-th value
 4     double helper(int *A, int *B, int lenA, int lenB, int k) {
 5         if (lenA > lenB) {
 6             return helper(B, A, lenB, lenA, k);
 7         }
 8         // lenA <= lenB
 9         if (lenA == 0) {
10             return B[k - 1];
11         }
12         if (1 == k) {
13             return min(A[0], B[0]);
14         }
15         int pa = min(lenA, k >> 1), pb = k - pa;
16         return (A[pa - 1] < B[pb - 1])?
17         helper(A + pa, B, lenA - pa, lenB, k - pa):
18         helper(A, B + pb, lenA, lenB - pb, k - pb);
19     }
20     /**
21      * @param A: An integer array.
22      * @param B: An integer array.
23      * @return: a double whose format is *.5 or *.0
24      */
25     double findMedianSortedArrays(vector<int> A, vector<int> B) {
26         // write your code here
27         int m = A.size();
28         int n = B.size();
29         return ((m + n) & 1)?
30         (helper(A.data(), B.data(), m, n, (m + n + 1)>>1)):
31         (((helper(A.data(), B.data(), m, n, ((m + n)>>1) + 1))+(helper(A.data(), B.data(), m, n, (m + n)>>1))) * .5);
32     }
33 };
复制代码

 


本文转自ZH奶酪博客园博客,原文链接:http://www.cnblogs.com/CheeseZH/p/5009273.html,如需转载请自行联系原作者

相关文章
|
算法 开发者 索引
二分算法详解
本文介绍了二分查找及其相关问题的解决方法,包括基本的二分查找、查找元素的第一个和最后一个位置、求平方根、搜索插入位置、寻找峰值和旋转数组中的最小值等问题。通过详细分析每种情况下的二分查找策略,如循环条件、区间划分及特殊情况处理,提供了清晰的代码实现。适用于算法初学者和需要巩固二分查找技巧的开发者。
455 18
二分算法详解
|
传感器 编解码 知识图谱
Google Earth Engine ——MOD17A2H V6总初级生产力(GPP)产品是一个具有500米分辨率的8天累积综合数据产品
Google Earth Engine ——MOD17A2H V6总初级生产力(GPP)产品是一个具有500米分辨率的8天累积综合数据产品
1577 0
Google Earth Engine ——MOD17A2H V6总初级生产力(GPP)产品是一个具有500米分辨率的8天累积综合数据产品
|
监控 安全 数据安全/隐私保护
【Docker项目实战】使用Docker部署OneTerm堡垒机
【8月更文挑战第6天】使用Docker部署OneTerm堡垒机
469 7
【Docker项目实战】使用Docker部署OneTerm堡垒机
|
Java 开发者
Java SPI机制大揭秘:动态加载服务提供者,一文让你彻底解锁!
【8月更文挑战第25天】Java SPI(服务提供者接口)是一种强大的扩展机制,允许程序在运行时动态加载服务实现。本文首先介绍SPI的基本原理——定义接口并通过配置文件指定其实现类,随后通过示例演示其实现过程。接着,对比分析了SPI与反射及插件机制的不同之处,强调SPI在灵活性与扩展性方面的优势。最后,基于不同场景推荐合适的选择策略,帮助读者深入理解并有效利用SPI机制。
472 1
|
网络协议 算法 安全
【专栏】RIP是一种古老的内部网关协议,使用距离矢量算法,基于跳数更新路由表,最古老的距离矢量协议
【4月更文挑战第28天】RIP是一种古老的内部网关协议,使用距离矢量算法,基于跳数更新路由表。其工作原理包括周期性更新、度量标准、路由表更新和防止计数到无穷问题的技术。RIP简单易用,适合小规模网络,但在大规模网络中效率低且有限制。随着OSPF和EIGRP等协议的发展,RIP在大型网络中的应用减少,但在中小型网络和遗留系统中仍有其地位。RIPv2的改进提高了安全性与灵活性。尽管逐渐被替代,RIP在理解路由协议基本概念和历史中仍具价值。
530 1
|
消息中间件 C# RocketMQ
MQ产品使用合集之设置rocketmq的timerMaxDelaySec时间出现报错如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
874 4
|
数据安全/隐私保护
APP - 支付宝怎么延时转账?能否撤回转账?
APP - 支付宝怎么延时转账?能否撤回转账?
3016 0
APP - 支付宝怎么延时转账?能否撤回转账?
|
自然语言处理 Java
BoolQueryBuilder 如何进行模糊查询 并且模糊过滤去除name为Ab的 【4月更文挑战第2天】
如果你想使用 BoolQueryBuilder 进行模糊查询,并且要排除那些 name 字段为特定值(如 "Ab")的文档,你可以使用 must_not 子句与 FuzzyQueryBuilder 和 TermQueryBuilder 组合。以下是如何在 Elasticsearch 中实现这一需求的示例: Java代码实现 假设你想对字段 description 进行模糊查询,并确保排除 name 字段为 "Ab" 的文档: java Copy code import org.elasticsearch.index.query.BoolQueryBuilder; import org.e
1624 3
|
监控 Java 关系型数据库
Elasticsearch之索引管理API(Index management)
Elasticsearch之索引管理API(Index management)
Elasticsearch之索引管理API(Index management)
|
Arthas 安全 Java
Agent内存马的自动分析与查杀(一)
Agent内存马的自动分析与查杀
1243 0
Agent内存马的自动分析与查杀(一)