题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 = [1, 3]
nums2 = [2]则中位数是 2.0
示例 2:nums1 = [1, 2]
nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.5来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的解决方法:

package com.xinyu.test;/*** Created by zy on 2019/4/16.*/
public class TestArray13 {public static void main(String[] args) {System.out.println(findMedianSortedArrays(new int[]{1,2},new int[]{-1,3}));}/***** 寻找两个有序数组的中位数给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 = [1, 3]nums2 = [2]则中位数是 2.0示例 2:nums1 = [1, 2]nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.5*/public static double findMedianSortedArrays(int[] nums1, int[] nums2) {int length1 = 0,length2 = 0;if (nums1 != null) {length1 = nums1.length;}if (nums2 != null) {length2 = nums2.length;}if (length1 == 0 ) {if (length2 % 2 == 0) {return (double) (nums2[length2/2] + nums2[length2/2 -1]) / 2;}else {return (double)nums2[length2/2];}}if (length2 == 0){if (length1 % 2 == 0) {return (double)(nums1[length1/2] + nums1[length1/2 -1]) / 2;}else {return (double)nums1[length1/2];}}
//        if (nums1[0] > nums2[0]) {
//            return findMedianSortedArrays(nums2,nums1);
//        }
//        int all = length1 + length2;
//        if (all %2 ==0) {
//            return  (double)(nums1[length1 -1] + nums2[0]) / 2;
//        }else {
//            return (double)nums1[length1 -1] < (double)nums2[0] ? (double)nums1[length1 -1] : (double)nums2[0] ;
//        }int arr[] = new int[length1 + length2];for (int i = 0, j = 0 , q = 0;i < length1 || (j < length2);){if (i < length1 && j < length2){if (nums1[i] < nums2[j]) {arr[q++] = nums1[i++];}else {arr[q++] = nums2[j++];}}else if (i < length1){arr[q++] = nums1[i++];}else if (j < length2){arr[q++] = nums2[j++];}}int all = length1 + length2;if (all % 2 == 0) {return (double)(arr[all/2] + arr[all/2 -1]) / 2;}else {return (double)arr[all/2];}}}

网上的解决方法:

package com.xinyu.test;/*** Created by zy on 2019/4/16.*/
public class TestArray13 {public static void main(String[] args) {System.out.println(findMedianSortedArrays(new int[]{1,2},new int[]{-1,3}));}/***** 寻找两个有序数组的中位数给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 = [1, 3]nums2 = [2]则中位数是 2.0示例 2:nums1 = [1, 2]nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.5*/public static double findMedianSortedArrays(int[] nums1, int[] nums2) {int length = nums1.length + nums2.length;if (length % 2 == 1) {return findKth(nums1, 0, nums2, 0, length / 2 + 1);}int small = findKth(nums1, 0, nums2, 0, length / 2);int big = findKth(nums1, 0, nums2, 0, length / 2 + 1);return (small + big) / 2.0;}/**** @param nums1 数组1* @param index1 表示数组1从第几位开始找* @param nums2 数组2* @param index2  表示数组2 从第几位开始找* @param k  k表示要找第几位,注意k 代表的不是索引,是索引加1* @return*/private static int findKth(int[] nums1, int index1, int[] nums2, int index2, int k) {// 如果第一个数组查找的位置是末尾,那么说明要找的数据不再数组1里面,那么直接从数组2里面找就可以。if (index1 == nums1.length) {return nums2[index2 + k - 1];}// 如果第二个数组查找的位置是末尾,那么说明要找的数据不再数组1里面,那么直接从数组1里面找就可以。if (index2 == nums2.length) {return nums1[index1 + k - 1];}//如果要找当前第一位,那么直接返回当前两个数组的最小值if (k == 1) {return Math.min(nums1[index1], nums2[index2]);}// 找到第k  位对应的,两个数组的数值  每次排除掉k/2 个数int num1 = index1 + k / 2 - 1 < nums1.length ? nums1[index1 + k / 2 - 1] : Integer.MAX_VALUE;int num2 = index2 + k / 2 - 1 < nums2.length ? nums2[index2 + k / 2 - 1] : Integer.MAX_VALUE;// 如果数组1 的比较小,那么数组1的查找开始位置要往前挪动k/2 个位置(即一下子排除了k/2 个元素),同时要找的位置减去k/2//注意 数学里面的k - k / 2  和java 里面的k - k / 2 不是等值的if (num1 < num2) {return findKth(nums1, index1 + k / 2, nums2, index2, k - k / 2);}// 如果数组2 的比较小,那么数组2的查找开始位置要往前挪动k/2 个位置(即一下子排除了k/2 个元素),同时要找的位置减去k/2return findKth(nums1, index1, nums2, index2 + k / 2, k - k / 2);}}

个人看了大概二个小时,终于看懂了。

大概逻辑是这样:

首先确定是需要寻找一个数,还是寻找两个数,如果是一个数,那么寻找第K 位数返回就可以了,如果是找两个数,那么就调用两次方法找到,求平均值就可以了。

关键在于寻找第k 个数。两个数组,我要找第k 个数,那么我可以 直接排除k/2 个数。怎么排除呢?
因为是两个有序数组,那么我找两个数组的第k/2 位,谁的值小,那么谁所在的数组开始查找的索引位置,直接往前挪k/2个位置。因为要找的数,肯定不在这里面。
然后依次再找第k -k/2 个数,因为前面已经挪了k/2 个数,那么要找的第k 个数,其实是在k - k/2 个位置。继续递归往后找。
直到k == 1 ,那么取最小的一个值。因为要找的是比较小的一个。或者有一个数组已经没有元素可以找了,那么返回另外一个数组的index + k-1 的数就可以了。

二分法查找,确实快。不需要一个一个遍历!学到了。

算法--------------------寻找两个有序数组的中位数相关推荐

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

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

  2. LeetCode4. 寻找两个有序数组的中位数

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

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

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

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

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

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

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

  6. 力扣寻找两个有序数组的中位数

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

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

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

  8. 分享一道力扣困难题~寻找两个有序数组的中位数(Java)

    目录 解题思路1 具体代码 解题思路2 具体代码 题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 .算法的时间复杂 ...

  9. 6 js 比较两个数组的差异_每天一道算法题(js)(3)——寻找两个有序数组的中位数...

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

最新文章

  1. nodejs这个过程POST求
  2. MongoDB如何一次插入多条json数据--转
  3. sketch软件_Sketch软件怎么用?怎么提升Sketch软件技巧?
  4. oracle使用shutdown immediate前应做
  5. PL/SQL详细介绍
  6. 微信小程序-简易计算器
  7. Spring MVC JSR-303验证框架之Hibernate-Validator
  8. python爬取豆瓣电影信息数据
  9. 检讨:丢了我女儿和项目设计感想
  10. 为什么接口在设计时所有的方法一般都要抛异常?
  11. 单片机音频谱曲软件_单片机音乐代码转换软件(Music Encode)
  12. 【第十届“泰迪杯”数据挖掘挑战赛】C题:疫情背景下的周边游需求图谱分析 问题一方案及Python实现
  13. aspack的简单脱壳,望大牛勿喷。
  14. opencv-python控制笔记本摄像头
  15. 小纸条:阿里云资源分享站
  16. 2020寒假牛客第一场——G eli和字符串
  17. 十分钟用Python画一片雪花
  18. gms认证流程_【热点资讯】详解Google GMS认证流程可大大缩短终端手机上市时间...
  19. SyGate4.0实现局域网共享上网
  20. 语言模型训练工具SRILM

热门文章

  1. oracle 云服务器cpu升级,Oracle 10g RAC 升级(CPU Update)之--升级CRS
  2. hook修改信息_React系列二十一 Hook(二)高级使用
  3. freebasic 编译linux,免费BASIC编译器下载
  4. 翻译java_翻译示例代码
  5. 错误LNK1107文件无效或损坏: 无法在 0x338 处读取
  6. CentOS Linux最常用命令及快捷键整理
  7. (转)理解android.intent.action.MAIN 与 android.intent.category.LAUNCHER
  8. C#: IntelliSense 貌似做错了一些事情。
  9. MVC5+EF6 入门完整教程七
  10. linux如何进入单用户模式