第四题:求两个有序数组的中位数(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

相关文章

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

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

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

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

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

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数组获取数组的长度读取某下的