博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode]题解(python):004-Median of Two Sorted Arrays
阅读量:6036 次
发布时间:2019-06-20

本文共 3254 字,大约阅读时间需要 10 分钟。

 

题目来源:


题意分析:

     这道题目是输入两个已经排好序的数组(长度为m,n),将这两个数组整合成一个数组,输出新数组的中位数。要求时间复杂度是(log(m + n)。比如如果输入[1,2,3],[3,4,5]。那么得到的新数组为[1,2,3,3,4,5]得到的中位数就是3.


题目思路:

     由于题目要求的时间复杂度是(log(m+n)),如果我们直接把两个数组整合一起,那么时间复杂度肯定超过(log(m+n))。所以整理肯定是不行的。那么还有什么方法吗?答案是肯定的。

     首先我们要先了解中位数的概念,中位数就是有序数组的中间那个数。那么如果我们将比中位数小的数和比中位数大的数去掉同样的个数,中位数的值也不会变化(数组的个数为偶数的时候另外讨论,因为那时候中位数是中间两个数的平均值,所以中位数旁边两个数不能去掉)

     所以我们不妨试着将数组长度不断缩短。这里不妨提出一个引理。假设有两个有序数组am,bn,他们整合后的有序数组为cn+m。他们的中位数分别是am/2,bn/2,c(m+n)/2。如果am/2 < bn/2,则 a0…m/2 <= c(m+n)/2 <= bn/2…n 。

     引理证明:

           假设 am/2 > c(m+n)/2 ,那么 bn/2  > c(m+n)/2,所以在数组am里有大于m/2个数大于c(m+n)/2,在数组bn里也有n/2个数大于c(m+n)/2

           也就是说在cn+m里有(m+n)/2个数大于c(m+n)/2,此时就c(m+n)/2不再是数组cn+m的中位数。

           所以a0…m/2 <= c(m+n)/2

           同理可得c(m+n)/2 <= bn/2…n 

    根据上述引理,我们不妨设m>n,那么我们根据判断两个数组的中位数大小,每个数组每次减少n/2长度,直到n为1。如此,我们通过减少log(n)次可以得到答案。这种方法的时间复杂度是(log(min(m,n)))。


代码(python):

1 class Solution(object): 2     def getMedian(self,nums): 3         size = len(nums) 4         if size == 0: 5             return [0,0] 6         if size % 2 == 1: 7             return [nums[size // 2],size // 2] 8         return [(float(nums[size // 2 - 1] + nums[size // 2])) / 2,size // 2] 9         10     def findMedianSortedArrays(self, nums1, nums2):11         """12         :type nums1: List[int]13         :type nums2: List[int]14         :rtype: float15         """16         size1 = len(nums1)17         size2 = len(nums2)18         if size1 < size2:19             return self.findMedianSortedArrays(nums2,nums1)20         m1 = self.getMedian(nums1)21         m2 = self.getMedian(nums2)22         if size2 == 0:23             return m1[0]24         if size2 == 1:25             if size1 == 1:26                 return (float(nums1[0] + nums2[0])) / 227             if size1 % 2 == 0:28                 if nums2[0] < nums1[size1 //2 - 1]:29                     return nums1[size1 // 2 - 1]30                 if nums2[0] > nums1[size1 // 2 ]:31                     return nums1[size1 // 2]32                 else:33                     return nums2[0]34             else:35                 if nums2[0] < nums1[size1 // 2 - 1]:36                     return (float(nums1[size1 // 2 - 1] + nums1[size1 // 2])) / 237                 if nums2[0] > nums1[size1 // 2 + 1]:38                     return (float(nums1[size1 // 2] + nums1[size1 // 2 + 1])) / 239                 else:40                     return (float(nums2[0] + nums1[size1 // 2])) / 241         if size2 % 2 == 0:42             if size1 % 2 == 0:43                 if nums2[size2 // 2 - 1] < nums1[size1 //2 - 1] and nums2[size2 // 2] > nums1[size1 // 2]:44                     return m1[0]45                 if nums1[size1 // 2 - 1] < nums2[size2 // 2 - 1] and nums1[size1 // 2] > nums2[size2 // 2]:46                     return m2[0]47         if m1[0] < m2[0]:48             return self.findMedianSortedArrays(nums1[m2[1]:],nums2[:size2 - m2[1]])49         if m1[0] > m2[0]:50             return self.findMedianSortedArrays(nums1[:size1 - m2[1]],nums2[m2[1]:])51         else:52             return m1[0]
View Code

 


PS:当两个数组长度都是偶数的时候,由于中位数和中间两个数相关,如果直接删减有可能把中位数的数值发生改变,比如:[1,6],[4,5],这种情况如果用上述算法,那么先得到[1],[4]最后得到2.5,然后最后答案应该是4.5,所以这种情况要另外讨论。

      还有,用python3.0要注意语法的不同,因为判断系统是用2.7的算法。3.0的’/’默认是浮点数,而在‘2.7’如果原来是整型的时候是整除。


转载请注明出处:

转载于:https://www.cnblogs.com/chruny/p/4789406.html

你可能感兴趣的文章
Retrofit 入门学习
查看>>
Spring Boot学习笔记
查看>>
python3存入redis是bytes
查看>>
laravel 集合接口
查看>>
C/C++二进制读写png文件
查看>>
thymleaf 常用th 标签
查看>>
RTB 广告系统
查看>>
Linux signal 那些事儿(2)【转】
查看>>
InfluxDB安装及配置
查看>>
Dynamics CRM Microsoft SQL Server 指定的数据库具有更高的版本号
查看>>
PAT Perfect Sequence (25)
查看>>
java.exe进程来源排查录
查看>>
点滴记录——Ubuntu 14.04中Solr与Tomcat整合安装
查看>>
C++实现KMP模式匹配算法
查看>>
ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立
查看>>
记录锁
查看>>
JSONObject与JSONArray的使用
查看>>
[SQL Server] 数据库日志文件自动增长导致连接超时的分析
查看>>
【常见Web应用安全问题】---6、Script source code disclosure
查看>>
<html:form>标签
查看>>