4. 寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
Python(参考leetcode答案)
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums=nums1+nums2
nums.sort()
t1,t2=divmod(len(nums),2)
return nums[t1] if t2 else (nums[t1]+nums[t1-1])/2
思路:这一段是看到题目后立即想起来的方案,因为python在处理列表方面十分强势。但人家要求时间复杂度时间复杂度为 O(log (m+n)),sort方法应该高于,所以只能采取别的方案。自己苦苦思考许久,也未能想出一二三,因此看了解析后去写,虽然懂了,但是写不出来,于是只能学习官方文档了。
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def getKthElement(k):
index1, index2 = 0, 0
while True:
# 特殊情况
if index1 == m:#如果当前节点数溢出1等于总结节点数证明数组执行完毕,则可以退出。
return nums2[index2 + k - 1]
if index2 == n:
return nums1[index1 + k - 1]
if k == 1:
return min(nums1[index1], nums2[index2])
# 正常情况
newIndex1 = min(index1 + k // 2 - 1, m - 1)#判断当前节点和结尾节点下标谁小
newIndex2 = min(index2 + k // 2 - 1, n - 1)#newindex是比对结束的下标。
pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]#取值
if pivot1 <= pivot2:
k -= newIndex1 - index1 + 1#如果结束坐标-开始坐标=0,但最起码会执行一个a[newIndex1],所以+1,其余同样。
index1 = newIndex1 + 1#index每次是下一个节点的下标
else:
k -= newIndex2 - index2 + 1
index2 = newIndex2 + 1
m, n = len(nums1), len(nums2)#首先获取各数组长度
totalLength = m + n#获取总长度
if totalLength % 2 == 1:#判断总长度是偶数还是奇数
return getKthElement((totalLength + 1) // 2)
else:
return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2
思路:采用二分法,将复杂度降低到log(),于是将本题思路转为需按照第(k)个小的数,因为数组是有序的,所以只需要在两个数组左侧寻找到第k个即可。具体思路可见官方解答。
GO(参考leetcode答案)
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
totalLength:=len(nums1)+len(nums2)
if totalLength%2==1 {
return float64(getKthElement(nums1,nums2,totalLength/2+1))
}else{
return float64(getKthElement(nums1,nums2,totalLength/2)+getKthElement(nums1,nums2,totalLength/2+1))/2.0
}
}
func getKthElement(nums1, nums2 []int, k int) int {
index1,index2:=0,0
for{
lennums1,lennums2:=len(nums1),len(nums2)
if index1==len(nums1){
return nums2[index2+k-1]
}else if index2==len(nums2){
return nums1[index1+k-1]
}
if k==1{
return min(nums1[index1],nums2[index2])
}
k2:=k/2
newindex1:=min(index1+k2-1,lennums1-1)
newindex2:=min(index2+k2-1,lennums2-1)
if nums1[newindex1]<=nums2[newindex2]{
k-=newindex1-index1+1
index1=newindex1+1
}else{
k-=newindex2-index2+1
index2=newindex2+1
}
}
return 0
}
func min(x,y int) int{
if x>y{
return y
}
return x
}