排序数组中的时间复杂度

Posted

技术标签:

【中文标题】排序数组中的时间复杂度【英文标题】:Time Complexity in Sorted Array 【发布时间】:2018-06-12 14:46:53 【问题描述】:

给定一个降序排列的数组,从这个数组中删除最小元素的时间复杂度是多少?

================================================ =

我的最小元素将在最后一个位置,所以 O(n) 找到它?或者我应该应用二进制搜索,因为数组是排序的,还是简单地 O(1) 到达最后?

【问题讨论】:

如果数组已排序,则根本不必搜索。如果您知道数组长度,则最小元素将位于索引length - 1 那么,时间复杂度是 O(1)? 是的。如果它是一个链表,那将是 O(n),因为您必须遍历整个列表才能到达最后一个元素。不过,这对于数组来说不是必需的。 实际上,哎呀,找到最小元素是 O(1),但如果复制了数组,删除将是 O(n)。这取决于您是制作较小的数组副本,还是只保留最后一个插槽为空。我认为这里需要定义“删除”。 如果我只是简单地删除而不复制原始数组? 【参考方案1】:

这实际上取决于您的意思是“从数组中删除”。您有一个按降序排序的数组,并且您想要删除最小元素。

假设数组是[5, 4, 3, 2, 1]。你知道数组有多大,所以找到最小元素是 O(1)。你只需索引a[a.length-1]

但是删除最后一个元素是什么意思呢?您可以轻松地将那里的值替换为哨兵值,以表示该位置不再使用,但是下次您尝试获取最小元素时,您必须访问a[a.length-1],然后进行反向扫描找到第一个使用的元素。当您删除更多项目时,这接近 O(n)。

或者您是否保留一个计数器来告诉您数组中实际使用了多少值?所以你会有一个变量count,告诉你哪个是最后一个元素。当你想获得你所拥有的最小元素时:

smallest = a[count];
count = count-1;

这仍然是 O(1),但它会在数组中留下未使用的项目。

但是如果要确保数组长度始终反映其中的项目数,则必须重新分配数组以使其更小。也就是 O(n)。

所以你的问题的答案是“视情况而定。”

【讨论】:

【参考方案2】:

由于数组是按降序排序的,假设数组中没有重复项,则始终保证最小元素位于数组的最后一个位置。可以在O(1)进行删除。

如果您需要对数组进行一系列删除,那么您可能需要调整删除的索引并指向数组的正确结束位置。这可以在恒定时间内完成。

因此总结起来,总时间复杂度为O(1)

【讨论】:

按降序排列,所以最小元素在数组的end。如果它在数组的开头,删除将是 O(n)。

以上是关于排序数组中的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

算法面试中的时间复杂度分析

计数排序及其时间复杂度代码(C++实现)应用场景

快排查找数组中的第K个最大元素

剑指offer-二维数组中的查找

力扣215.数组中的第K个最大元素

[算法]数组排序之后相邻数的最大差值