There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays.

The overall run time complexity should be O(log(m + n)).

分析

本题更经典通用的描述方式时:

给定2个有序数组,找出2个数组中所有元素中第k大的元素。

思路1

直观思路就是类似merge-sort,将2个数组merge成一个数组,即可得到第k大的值,但是时间复杂度O(m+n);

思路2

然后我们仅需要第k大的元素,不需要排序这个复杂的操作:可以定义一个计数器m,表示找到了第m大的元素;同时指针pa,pb分别指向数组A,B的第一个元素,使用merge-sort的方式,当A的当前元素小于B的当前元素时:pa++, m++,当*pb < *pa时,pb++, m++。最终当m等于k时,就得到了第k大的元素。时间复杂度O(k),但是当k接近于m+n时,复杂度还是O(m+n);

思路3

从题目中的要求O(log(m+n))可以联想到肯定要用到二分查找的思想

那么有没有更好的方案?我们可以考虑从k入手。如果我们每次能够删除一个一定处于第k大元素之前的元素,那么需要进行k次。但是如果我们每次都能删除一半呢?可以利用A,B有序的信息,类似二分查找,也是充分利用有序。

假设A 和B 的元素个数都大于k/2,我们将A 的第k/2 个元素(即A[k/2-1])和B 的第k/2个元素(即B[k/2-1])进行比较,有以下三种情况(为了简化这里先假设k 为偶数,所得到的结论对于k 是奇数也是成立的):

- A[k/2 - 1] == B[k/2 - 1];

- A[k/2 - 1] > B[k/2 - 1];

- A[k/2 - 1] < B[k/2 - 1];

如果A[k/2 - 1] < B[k/2 - 1] ,意味着 A[0] 到 A[k/2 - 1] 的元素一定小于 A+B 第k大的元素。因此可以放心的删除A数组中的这k/2个元素;

同理,A[k/2 - 1] > B[k/2 - 1];可以删除B数组中的k/2个元素;

当A[k/2 - 1] == B[k/2 - 1] 时,说明找到了第k大的元素,直接返回A[k/2 - 1] 或B[k/2 - 1]的值。

因此可以写一个递归实现,递归终止条件是什么呢?

- A或B为空时,直接返回A[k-1] 或 B[k-1]

- 当k = 1时,返回min(A[0], B[0]) //第1小表示第一个元素

- 当A[k/2 - 1] == B[k/2 - 1] 时,返回A[k/2 - 1] 或B[k/2 - 1]

C语言实现

static int find_kth(int* A, int m,int* B, int n, int k);

static int min(p, q) {return (p < q) ? p : q;}

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {

int m = nums1Size;

int n = nums2Size;

int total = m+n;

int k = total/2;

if(total & 0x01) {

return find_kth(nums1, m, nums2, n, k+1); //奇数,返回唯一中间值

} else {

return (find_kth(nums1, m, nums2, n, k) + find_kth(nums1, m, nums2, n, k+1)) / 2.0; //偶数,返回中间2个的平均值

}

}

//找到A,B组合中第k小的值: AB[k-1]

int find_kth(int* A, int m,int* B, int n, int k) {

//假设m都小于n

if (m > n)

return find_kth(B, n, A, m, k);

if (m == 0)

return B[k-1];

if (k == 1) //终止条件

return min(A[0], B[0]);

int i_a = min(m, k/2);

int i_b = k - i_a;

if (A[i_a-1] < B[i_b-1])

return find_kth(A+i_a, m-i_a, B, n, k-i_a);

else if (A[i_a-1] > B[i_b-1])

return find_kth(A, m, B+i_b, n-i_b, k-i_b);

else

return A[i_a-1];

}

C语言求一个数组中第k大的数,leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值...相关推荐

  1. [leetcode] Median of Two Sorted Arrays 寻找两个有序数组的中位数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  2. LeetCode4寻找两个有序数组的中位数(二分查找+分治)

    目录 1.题目 2.分析 3.代码 二分查找:绝大多数二分查找问题利用的是单调性,也有一些例外)或者题目本身蕴含的可以逐渐缩小问题规模的特性解决问题.时间复杂度log级. 分治法的设计思想是:将一个难 ...

  3. 算法—两个有序数组的中位数 Median of Two Sorted Arrays

    关注微信公众号:CodingTechWork,一起学习进步. 题目 There are two sorted arrays nums1 and nums2 of size m and n respec ...

  4. 20191016:(leetcode习题)寻找两个有序数组的中位数

    寻找两个有序数组的中位数 题目 大致思路 代码实现 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log( ...

  5. C语言——求第n个斐波那契数

    C语言--求第n个斐波那契数 写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: f(n)=f(n-1)+f(n-2),当n>1时,当n=0,f(0)=0 ...

  6. C语言求100-200之间不能被3整除的数

    例13:C语言实现统计100~200之间的不能被3整除的数. 解题思路:需要对100-200之间的每一个数进行遍历,如果不能被3整除,就将此数输出,若能被3整除,就不输出此数,读者可以考虑使用这个语句 ...

  7. 【LeetCode】004 Median of Two Sorted Arrays 两个排序数组合并后的中位数

    题目:LeetCode 004 Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m an ...

  8. 算法--------------------寻找两个有序数组的中位数

    题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假设 nums1 和 num ...

  9. 两个有序数组的中位数 python_Python寻找两个有序数组的中位数实例详解

    Python寻找两个有序数组的中位数 审题: 1.找出意味着这是一个查找算法题 2.算法复杂度log级别,就是提示你是二分查找 3.二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: ...

最新文章

  1. mysql查看修改记录_(转)MySql中监视增删改查和查看日志记录
  2. 实战SSM_O2O商铺_38【商品类别】解除商品与商品类别的关联
  3. VisualVM——JDK自带的性能分析工具
  4. 华为服务器系统关机命令,云服务器关机指令
  5. Vagrant 快速入门
  6. 导出到文件_Java项目导出可运行的jar文件
  7. 使用GDAL将下载的Google卫星图像转为带坐标的tif
  8. TF2.0—tf.keras.layers.Lambda
  9. HeadFirst jsp 08 无脚本JSP
  10. DPDK QOS2 -- DPDK的QOS框架
  11. 中基协会长洪磊:尽快制定大类资产配置管理办法 推非保本理财转型
  12. JDBC单独了解一下
  13. 手机迅雷打不开html,迅雷打不开了怎么办
  14. 笔记本计算机在桌面显示,笔记本电脑开机后不显示桌面该怎么处理
  15. 计算机字的符号,特殊符号图案大全
  16. pmf-automl源码分析
  17. 别费劲找站长工具共享VIP了 这个工具也不错
  18. 如何解决中小企业融资难问题
  19. 保姆级人工智能学习成长路径
  20. 乐游api接口平台(接口商)

热门文章

  1. LeetCode 1383. 最大的团队表现值(贪心,优先队列,难)
  2. LeetCode 1332. 删除回文子序列
  3. python多线程实现方式_python中实现多线程有几种方式?
  4. 电商网站(Django框架)—— 大纲内容与基本功能分析
  5. java中excel文件导入数据库中_〖JAVE经验〗java中Excel导入数据库里
  6. 开启NLP新时代的BERT模型,真的好上手吗?
  7. 别让数据坑了你!用置信学习找出错误标注(附开源实现)
  8. 2018最新Java面试78题:数据结构+网络+NoSQL+分布式架构
  9. 会议交流—PPT下载|DataFunSummit2022:知识图谱在线峰会PPT合集!
  10. 5 计算机组成原理第四章 指令系统