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

本文主要是介绍算法--------------------寻找两个有序数组的中位数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

给定两个大小为 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 的数就可以了。

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

这篇关于算法--------------------寻找两个有序数组的中位数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1131029

相关文章

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n