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

devtools/2024/9/23 9:50:31/

题目描述:

给定两个大小为 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 实现

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 实现

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) 分别是两个数组的长度。这是因为我们主要是在较短的数组上进行二分查找。


http://www.ppmy.cn/devtools/100829.html

相关文章

Java开发笔记-spring的@schedule低级错误

最近在追一个数据库等待锁超时&#xff0c;数据库死锁导致的数据问题。考虑是定时任务占用锁&#xff0c;触发器sql冲突导致。于是在研究程序日志。发现了另外一个问题&#xff1a;我的定时任务明明注解的 每天七点执行&#xff0c;他偏偏9点才执行。 之前也没去管它&#xff0…

Nim游戏

Nim游戏 给定 n堆石子&#xff0c;两位玩家轮流操作&#xff0c;每次操作可以从任意一堆石子中拿走任意数量的石子&#xff08;可以拿完&#xff0c;但不能不拿&#xff09;&#xff0c;最后无法进行操作的人视为失败。 问如果两人都采用最优策略&#xff0c;先手是否必胜。 输…

使用OpenCV库来捕获摄像头视频流,并按指定格式保存

今天我们来使用OpenCV库来捕获摄像头视频流&#xff0c;并将其保存为AVI格式的视频文件&#xff0c; 代码的主要功能包括&#xff1a; 初始化摄像头捕获对象。设置视频编解码器和输出文件路径。循环读取视频帧&#xff0c;处理并保存到文件中。显示处理后的视频帧。按下q键退…

QT 简易网页信息抓取程序模板基础代码

有些网页爬不了&#xff0c;只是一个简单的代码。 项目结构 NetBugBaseCode.pro #------------------------------------------------- # # Project created by QtCreator 2024-08-26T15:13:10 # #-------------------------------------------------QT core gui netw…

git仓库删除某个历史提交

目录 问题情况1情况2 问题 如果我们在开发过程中&#xff0c;存在一些验证性的提交或者失误性的提交&#xff0c;那么这些提交我们不想要了&#xff0c;怎么办&#xff1f; 情况1 如果是想要删除某个commitid之后的所有提交 那么git reset 可以满足你 git reset --hard 你要…

prometheus 普罗米修斯安装部署

一、安装Prometheus(普罗米修斯)准备阶段 1.#####必须:时钟同步#####,Prometheus****服务端与被监控端 2.创建软件目录 mkdir /Prometheus 二、下载软件 1.上传Prometheus软件 下载地址:https://prometheus.io/download/ prometheus-2.54.0-rc.1.linux-amd64.ta…

【C/C++】C语言字符串数组排序问题

在C语言中&#xff0c;可以使用strcmp函数对字符串进行排序。 strcmp函数比较两个字符串的大小&#xff0c;并返回一个整数值。 如果返回值大于0&#xff0c;则表示第一个字符串比第二个字符串大。如果返回值等于0&#xff0c;则表示两个字符串相等&#xff1b;如果返回值小于0…

鸿蒙ArkTs使用axios发起网络请求并对请求参数加密

下载安装axios ohpm install ohos/axios需要权限 {"module": {"requestPermissions": [{"name": "ohos.permission.INTERNET","reason": "$string:permission_internet","usedScene": {"abiliti…