第四题:求两个有序数组的中位数(Median of Two Sorted Arrays)

2024-08-24 13:28

本文主要是介绍第四题:求两个有序数组的中位数(Median of Two Sorted Arrays),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2,请你找出这两个有序数组的中位数。

示例:

  1. 输入:nums1 = [1, 3]nums2 = [2]
    输出:2.0

  2. 输入:nums1 = [1, 2]nums2 = [3, 4]
    输出:2.5

要求: 你必须在对数时间复杂度 O(log(min(m, n))) 内解决这个问题。

解题思路

  1. 二分查找方法(最优解法)

    这个问题的核心是利用二分查找算法在两个有序数组中找到中位数。我们可以将问题转化为在两个数组中寻找一个分割点,使得左侧的元素总是小于右侧的元素,并且左侧的元素数量与右侧的元素数量尽可能相等。

    具体步骤如下:

    1. 确保 nums1 的长度小于等于 nums2,如果不是,则交换它们。

    2. 对于较短的数组 nums1,使用二分查找来确定分割点。分割点将数组 nums1 划分为 left1 和 right1,同时在 nums2 中确定对应的分割点 left2 和 right2

    3. 根据当前的分割点计算 left1right1left2right2,然后调整分割点以满足以下条件:

      • left1 和 left2 的最大值要小于等于 right1 和 right2 的最小值。
    4. 如果分割点满足条件,则根据总元素个数的奇偶性计算中位数。

    5. 如果分割点不满足条件,则根据条件调整分割点,继续二分查找。

C 语言实现

#include <stdio.h>
#include <limits.h>double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {if (nums1Size > nums2Size) {int* tempArr = nums1;nums1 = nums2;nums2 = tempArr;int tempSize = nums1Size;nums1Size = nums2Size;nums2Size = tempSize;}int imin = 0, imax = nums1Size, half_len = (nums1Size + nums2Size + 1) / 2;while (imin <= imax) {int i = (imin + imax) / 2;int j = half_len - i;if (i < nums1Size && nums2[j - 1] > nums1[i]) {imin = i + 1;} else if (i > 0 && nums1[i - 1] > nums2[j]) {imax = i - 1;} else {int max_of_left, min_of_right;if (i == 0) max_of_left = nums2[j - 1];else if (j == 0) max_of_left = nums1[i - 1];else max_of_left = (nums1[i - 1] > nums2[j - 1]) ? nums1[i - 1] : nums2[j - 1];if ((nums1Size + nums2Size) % 2 == 1) return max_of_left;if (i == nums1Size) min_of_right = nums2[j];else if (j == nums2Size) min_of_right = nums1[i];else min_of_right = (nums1[i] < nums2[j]) ? nums1[i] : nums2[j];return (max_of_left + min_of_right) / 2.0;}}return 0.0;
}

Java 实现

public class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {if (nums1.length > nums2.length) {int[] temp = nums1;nums1 = nums2;nums2 = temp;}int x = nums1.length;int y = nums2.length;int low = 0, high = x;while (low <= high) {int partitionX = (low + high) / 2;int partitionY = (x + y + 1) / 2 - partitionX;int maxX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1];int minX = (partitionX == x) ? Integer.MAX_VALUE : nums1[partitionX];int maxY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1];int minY = (partitionY == y) ? Integer.MAX_VALUE : nums2[partitionY];if (maxX <= minY && maxY <= minX) {if ((x + y) % 2 == 0) {return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2.0;} else {return Math.max(maxX, maxY);}} else if (maxX > minY) {high = partitionX - 1;} else {low = partitionX + 1;}}throw new IllegalArgumentException("Input arrays are not sorted.");}
}

Python 实现

def findMedianSortedArrays(nums1, nums2):if len(nums1) > len(nums2):nums1, nums2 = nums2, nums1x, y = len(nums1), len(nums2)low, high = 0, xwhile low <= high:partitionX = (low + high) // 2partitionY = (x + y + 1) // 2 - partitionXmaxX = float('-inf') if partitionX == 0 else nums1[partitionX - 1]minX = float('inf') if partitionX == x else nums1[partitionX]maxY = float('-inf') if partitionY == 0 else nums2[partitionY - 1]minY = float('inf') if partitionY == y else nums2[partitionY]if maxX <= minY and maxY <= minX:if (x + y) % 2 == 0:return (max(maxX, maxY) + min(minX, minY)) / 2.0else:return max(maxX, maxY)elif maxX > minY:high = partitionX - 1else:low = partitionX + 1raise ValueError("Input arrays are not sorted.")

时间复杂度

所有三种实现的方法的时间复杂度都是 (O(\log(\min(m, n)))),其中 (m) 和 (n) 分别是两个数组的长度。这是因为我们主要是在较短的数组上进行二分查找。

这篇关于第四题:求两个有序数组的中位数(Median of Two Sorted Arrays)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102605

相关文章

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Python中的sort()和sorted()用法示例解析

《Python中的sort()和sorted()用法示例解析》本文给大家介绍Python中list.sort()和sorted()的使用区别,详细介绍其参数功能及Timsort排序算法特性,涵盖自适应... 目录一、list.sort()参数说明常用内置函数基本用法示例自定义函数示例lambda表达式示例o

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Java中Arrays类和Collections类常用方法示例详解

《Java中Arrays类和Collections类常用方法示例详解》本文总结了Java中Arrays和Collections类的常用方法,涵盖数组填充、排序、搜索、复制、列表转换等操作,帮助开发者高... 目录Arrays.fill()相关用法Arrays.toString()Arrays.sort()A

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam