给出两个有序的数字列表,长度分别为m,n。找到这两个列表中的中间值。(第一次出现了时间复杂度的要求噢)
#例子一:总长度为奇数
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
#例子二:总长度为偶数
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
仔细分析题目,nums1和nums2都已经是排好序了的,这就大大的降低了难度,让找到两个列表的中间值,其实我们可以拓展为找到两个列表的第k个值。当然这个是拓展部分了,对于这个题目,有不同的思路,最简单粗暴的就是将两个列表合并,之后进行排序,排好序后进行寻找中间值就简单了。但是用传统的先合并再排序,效率想必会很低~
我们发现对于两个已经有序的列表(从小到大),其实有一个更优的排序方式:从小到大,依次进行列表元素的比较(为方便表述,称两个列表为A,B),较小值放到一个新列表中,比如A中该位置的值较小,将其放到新的列表C中,同时将A列表下一个值继续与B中当前位置元素进行比较,以此类推。我们称其为双指针法这样的比较次数就比先合并在排序小很多啦!代码如下:
def FindMidium(nums1,nums2):
n1=len(nums1)
n2=len(nums2)
"""首先将nums1,nums2合并为一个基本有序的列表(小数在左,大数在右端)"""
#创建一个新列表,为了合并两个列表
list=[0]*(n1+n2)
"""当输入两个列表都还存在元素没进行比较的时候,循环进行对比
并将较小值放入新列表,同时较小元素的列表和新列表索引加一"""
i_1,i_2,i=0,0,0
while i_1<n1 and i_2<n2:
if nums1[i_1]<nums2[i_2]:
list[i]=nums1[i_1]
i_1+=1
i+=1
elif nums1[i_1]>nums2[i_2]:
list[i] = nums2[i_2]
i_2 += 1
i += 1
"""当存在某一个列表所有元素已经比较完,即排好了序
剩下那个列表剩下的值直接放入新列表对应位置即可"""
if i<n1:
list[i:]=nums1[i_1:]
else:
list[i:] = nums2[i_2:]
"""取list列表的中位数"""
if len(list)%2!=0:
return list[len(list)//2]
else:
return (list[len(list)//2-1]+list[len(list)//2])/2
"""测试代码"""
nums1 = [1, 2]
nums2 = [3, 4]
a=FindMidium(nums1,nums2)
print(a)