我正在处理一个问题,它包含一个有 n 个元素的已排序数组,后面跟着一个长度为:
- O(logn)
- O(sqrt(n))
的未排序数组。如何高效地对整个列表进行排序?在上述两种情况下应该使用哪种排序方法?
的未排序数组。如何高效地对整个列表进行排序?在上述两种情况下应该使用哪种排序方法?
由于将单个元素插入数组并保持其排序的时间复杂度为O(n)
,因此您无法获得比这更好的结果。
因此,在两种情况下 - 对较小的数组进行排序,然后使用merge(part1,part2)
将是O(n)
,因此在渐近复杂度方面是最优的。
O(logn*loglog(n))
或 O(sqrt(n)*log(sqrt(n)))
分别是两种情况。merge(part1,part2)
:O(n+logn)
或 O(n+sqrt(n))
,无论如何都是O(n)
1。因此,两种情况的总复杂度为O(n)
,这对于这个问题来说是最优的。
(1)它是真实的,因为对于每个k>0,m>0
,log(n)^k
渐进地小于n^m
,特别是对于k=1,m=1/2
。
证明基于两边取对数:
log (log(n)^k) <? log(n^m) <=>
k*log(log(n)) <? m*log(n)
sqrt(n)*log(n) < sqrt(n) * n^1/2 = n
,因此它确实是O(n)
。O(sqrt(N)*log(N)) < O(N)
这一点不太明显。 - salvak,m
,log(n)^k
在渐进意义下都比n^m
小,特别地,当k=1,m=1/2
时。 - amit简单来说,将第二部分进行排序并与第一部分合并(与归并排序相同)。两个已排序子数组的合并步骤是O(n)。
part1
和part2
的大小分别为O(log n)和O(sqrt(n))。因此,如果您从part2
中选择一个元素,并通过使用二分搜索在part1
中找到该位置,然后递归执行此操作,直到part2
的元素为空,总运行时间将变为O(sqrt(n) log(log n))。