LeetCode-4 寻找两个正序数组的中位数
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
题目描述
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
解题思路
单从题干来说,这就是一道归并排序题,最初的想法是将两个vector数量求和除以二得到n,然后归并排序找出第n个数来,不出所料,时间超出限制。
困难题果然不简单,关键是“算法的时间复杂度应该为 O(log (m+n)) ”,如果使用归并排序的方法,那么时间复杂度必然是O(m+n),还是太久了。
这个时候其实理所当然应该想到二分法,不过还有另一种解法也十分的有趣。
假设两个数组分别为A,B,数组程度分别为m,n:
中位数的意义就是将一个数组平均的分成两个部分,这两个部分有相同数目的元素,对于未合并的两个数组来说也一样,假设我们将A数组在第i个地方分开,B数组在第j个地方分开,那么A[i]或者B[j]是中位数的必须满足的条件就是:
1、i + j = m - i + n - j(m+n为偶数时)或者i + j = m - i + n - j + 1(m + n为奇数)。
2、A[i - 1] <= B[j] 并且 B[j - 1] <= A[i].
通过条件1,在确定i的情况下可以确定j的值,那么我们需要使用二分法找到一个i满足条件2便可以找到中位数。
在确定i之后,比较A中第i个数和B中第j个数,如果m+n是奇数,那么A中第i个数和B中第j个数中最大的那个就是中位数,如果m+n是偶数,那么还需要找到划分出来的后数组中最小值,即A中第i+1个数和B中第j+1个数中最大的那个,将前数组的最大值与后数组的最小值求均值,就是中位数了。
源码展示
class Solution: def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: m=min(len(nums1),len(nums2)) n=max(len(nums1),len(nums2)) A=nums1 if len(nums1)<len(nums2) else nums2 B=nums2 if len(nums2)>len(nums1) else nums1 imin=0 imax=m while imin<=imax: i=int((imin+imax)/2) j=int((m+n+1)/2-i) if i<imax and B[j-1]>A[i]: imin=i+1 elif i>imin and A[i-1]>B[j]: imax=i-1 else: leftx=0 if i==0 : leftx=B[j-1] elif j==0 : leftx=A[i-1] else: leftx=max(A[i-1],B[j-1]) if (m+n)%2==1: return leftx rightx=0 if i==m :rightx=B[j] elif j==n :rightx=A[i] else: rightx=min(A[i],B[j]) return (leftx+rightx)/2.0
运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了