📅  最后修改于: 2023-12-03 14:43:43.404000             🧑  作者: Mango
中位数是一个序列中排在中间的数,对于一个有奇数个元素的序列,中位数就是排序后中间那个数;对于一个有偶数个元素的序列,中位数就是排序后中间两个数的平均数。
现在,给定一个序列和K个附加整数,你需要在加入这K个数后,求出新序列的中位数。
最简单暴力的方法是将K个附加整数一个一个地加到序列中,然后再排序,最后求得中位数。这种算法的时间复杂度是 O((N+K)log(N+K)),其中N是原序列的长度。时间复杂度较高,不适用于大规模数据集。
我们可以通过二分法,在新序列中找到中位数所在的位置。如果新序列的长度是奇数,那么中位数的位置就是 len(new_list) // 2(整数除法);如果新序列的长度是偶数,那么中位数的位置是 len(new_list) // 2 - 1 和 len(new_list) // 2。
然后我们可以通过双指针的方式,同时在原序列和新序列中移动指针,找到新序列中的中位数。具体的实现过程如下:
def findMedian(list1: List[int], k: int, list2: List[int]):
n = len(list1)
m = len(list2)
def get_kth_element(kth: int) -> int:
index1, index2 = 0, 0
while True:
if index1 == n:
return list2[index2 + kth - 1]
if index2 == m:
return list1[index1 + kth - 1]
if kth == 1:
return min(list1[index1], list2[index2])
new_index1 = min(index1 + kth // 2, n) - 1
new_index2 = min(index2 + kth // 2, m) - 1
pivot1, pivot2 = list1[new_index1], list2[new_index2]
if pivot1 <= pivot2:
kth -= new_index1 - index1 + 1
index1 = new_index1 + 1
else:
kth -= new_index2 - index2 + 1
index2 = new_index2 + 1
total = n + m
if total % 2 == 1:
return get_kth_element((total + 1) // 2)
else:
return (get_kth_element(total // 2) + get_kth_element(total // 2 + 1)) / 2
通过二分查找+双指针的方式,可以在时间复杂度为 O(log(N+K)) 的情况下,找到新序列中的中位数。这种方法时间复杂度较低,适用于大规模数据集。