leetcode上第四道题,如下。

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

题目很简洁,首先要搞懂中位数的概念,这玩意和平均数是有差别的。一开始我就搞错了,把中位数和平均数搞混了,结果做了半天结果越来越离谱。百度的中位数概念如下:

中位数是按顺序排列的一组数据中居于中间位置的数,即在这组数据中,有一半的数据比他大,有一半的数据比他小。

如果序列个数为奇数,则中间的数就是中位数,只有一个,如果个数为偶数的话,则中位数是中间两位数的均值,需要找到两个数求平均值,如果个数为奇数,其中位数为((n+1)/2)== ((n+2)/2),对于偶数,中位数为分别为((n+2)/2)和(n/2),其中偶数情况下N/2 == (N+1)/2,因此不论奇数还是偶数,我们都可以求((n+2)/2和((n+1)/2),然后取平均值。

如果没有时间复杂度要求的话很简单,俩数组重排列后取中位数即可,但是题目要求是时间复杂度为O(log(m + n))。网上的同志说看到时间复杂度为log的基本上都是二分法,这个我之前不知道,水平不够高。看了一位大神的解法,明白了。这道题可以这样来看,求俩有序数组的中位数,相当于在一个有序的数组里找到第K个数,假设数组A的起始搜索位置和数组B的起始搜索位置分别是i和j,如果起始位置大于数组长度的话,说明在当前数组已经没有数了,这时候直接去另一个数组里取第K个数即可。如果K为1的话,返回俩数组中第一个值当中的最小值即可,如果是其它情况,我们对K进行二分,先找到K/2,假设K' = K/2,找到则排除一半,再在找另一半即可,首先判断起始位置加上要找的数长度是否超过数组长度,如果超过的话,这时候另外一个数组(假设为B)里前K' 个数是可以省略的,因为我们要找第K个数,那么它绝对不会在B的K‘ 里面,因为长度不够。举个例子,数组A={1},数组B={0,2,4,6,7,8,9,12},一共9个数,假设是有序数组,我们知道第五个数就是中位数,这里我们先二分K,5/2取余 = 2,数组A和B的初始查找位置都为0,对于A而言,2大于它的长度1,这时候我们可以排除掉数组B中的前两个元素了,因为第五个数肯定要在前两个数后面,这时候我们就排除掉两个,这时候需要移动B的起始位置,j = j + K',剩下三个,同样的道理,对三进行二分。还有一种情况是两个数组里从各自的起始位置都存在K‘个数,这时候就需要比较A[ i + K' ]和B[ j + K' ],哪个大则移动另外一个数组的起始指针K’ 位,相等则移动任意一个。这时候就排除了K‘,我们只需要递归查找第K - K',同理,继续二分,K’ = (K - K') / 2; 直到K = 1,或者某个数组起始位置超出数组长度,这时候直接返回另一个数组里对应K‘即实我们要找的值。

总的来说,思路很巧妙,没有经过训练很难短时间内想到。此外就是二分法通常都需要递归调用。

下面是该问题的C代码实现。

#define MIN(a,b) ((a) > (b) ? (b) : (a))int GetKth(int *nums1, int nums1Size, int start1, int *nums2, int nums2Size, int start2, int k)
{int K1, K2;if (start1 + 1 > nums1Size)return nums2[start2 + k - 1];if (start2 + 1 > nums2Size)return nums1[start1 + k - 1];if (k == 1)return MIN(nums1[start1], nums2[start2]);if (start1 + k / 2 > nums1Size)return GetKth(nums1, nums1Size, start1, nums2, nums2Size, start2 + k / 2, k - k / 2);if (start2 + k / 2 > nums2Size)return GetKth(nums1, nums1Size, start1 + k / 2, nums2, nums2Size, start2, k - k / 2);K1 = nums1[start1 + k / 2 - 1];K2 = nums2[start2 + k / 2 - 1];if (K1 < K2)return  GetKth(nums1, nums1Size, start1 + k / 2, nums2, nums2Size, start2, k - k / 2);elsereturn  GetKth(nums1, nums1Size, start1, nums2, nums2Size, start2 + k / 2, k - k / 2);
}double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){int k1 = (nums1Size + nums2Size + 1)/2;int k2 = (nums1Size + nums2Size + 2)/2;//奇数和偶数一样return ((double)GetKth(nums1, nums1Size, 0, nums2, nums2Size, 0, k1) + (double)GetKth(nums1, nums1Size, 0, nums2, nums2Size, 0, k2))/2;
}

参考目录:

1. https://www.cnblogs.com/grandyang/p/4465932.html

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

leetcode 4. 寻找两个有序数组的中位数,c语言相关推荐

  1. 【LeetCode】寻找两个有序数组的中位数【性质分析+二分】

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

  2. LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)

    文章目录 1. 题目 2. 解题 2.1 合并数组 2.2 优化2.1解法,双指针 2.3 二分法(找第k个数) 2.4 切分法 1. 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 n ...

  3. [leetcode] 4 寻找两个有序数组的中位数(二分+递归查找第K小数)(重要)

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

  4. Leetcode(4)寻找两个有序数组的中位数

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

  5. LeetCode 4.寻找两个有序数组的中位数

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

  6. leetcode 4 --- 寻找两个有序数组的中位数

    1 题目 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的中位数. 进阶:设计一个时间复杂度为 O(log (m+n)) 的算法. 2 解 ...

  7. [leetcode] 4. 寻找两个有序数组的中位数

    官方题解:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu- ...

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

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

  9. LeetCode(Python实现)—寻找两个有序数组的中位数

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

最新文章

  1. 浅谈Base64编码算法
  2. c++申请内存空间_有没有想过:malloc分配的内存空间地址连续吗
  3. 想拿下互联网大厂OFFER,都需要准备什么?
  4. Linux关于文件的权限笔记
  5. 2019 秋招提前批蘑菇街一面面经(带答案)
  6. 基于张量秩一分解的多目标跟踪方法
  7. 不变子空间与线性变换的矩阵之间的关系
  8. EGE基础:鼠标消息篇
  9. 软考高级 真题 2016年上半年 信息系统项目管理师 综合知识
  10. graphpad饼状图_应用 Graphpad 统计作图,助你写文章事半功倍
  11. win2008计算机无法访问,win2008共享资源无法访问故障的应对措施
  12. 2u机架式服务器作用,不仅是一款通用的2U机架式服务器还具有足够的扩展力
  13. 线上拼团活动方案怎么制作设计?
  14. 抽奖逻辑java_Java 利用binarySearch实现抽奖计算逻辑
  15. C/C++编程:long long类型
  16. Office2016安装报错:1935安装程序集组件发生错误
  17. 如何简单的生成rss地址_什么是RSS(真正的简单企业联合组织)?
  18. 模拟Android内存不足 activity回收 值保存 状态恢复
  19. zabbix-agent报active check configuration update from[] started to fail(timeout)【2】
  20. linux做m3u8推流服务器,linux搭建nginx流服务器,OBS推流,VCL拉流播放

热门文章

  1. (学)DEV在设计界面部分组件显示红叉并报错的问题
  2. MVC 学习日志1(上)
  3. 基于迭代次数和分类准确率的两种排序
  4. 行转列 oracle nvl,oracle 行转列 decode
  5. php smarty安装,php smarty 安装 、配置、使用 及缓存cache的配置使用
  6. 1.10 梯度消失与梯度爆炸-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  7. 3.9 神经网络解决多分类问题-机器学习笔记-斯坦福吴恩达教授
  8. 每天学习python 30分钟 -了解python - 看懂#!/usr/bin/python
  9. SOPC第四课 按键中断
  10. 更新网盘(云存储)功能需求,免费网盘需求,手机数据备份