性能:在 ARR(允许平局)中查找最大值的索引

performance: find the index of max value in an arr(tie allowed)

本文关键字:查找 最大值 索引 许平局 ARR 性能      更新时间:2023-10-16

就像标题和顺便说一句一样,这只是出于好奇,这不是一个家庭作业问题。对于CS专业的人来说,这似乎是微不足道的。问题是我想在数组中找到最大值的索引。基本上我有两种方法。

扫描
  1. 并找到最大值,然后扫描两次以获取索引向量

  2. 扫描
  3. 并找到最大值,沿着此扫描构造索引数组,如果那里有更好的索引数组,则放弃。

我现在应该如何权衡这两种方法的性能(我想主要是时间复杂度)?这对我来说很难,因为我什至不知道第二种方法的最坏情况应该是什么!这不是一个难题。但我只是想知道如何处理这个问题,或者我应该如何谷歌这种类型的问题来获得答案。

在复杂性方面:

扫描

并找到最大值,
然后扫描两次以获得索引的向量

第一次扫描是O(n)
第二次扫描是O(n)+k次插入(k,最大值的数量)vector::push_back已经摊销了O(1)的复杂性。 所以总O(2 * n + k)可以简化为O(n)k <= n

扫描

并找到最大值,
沿着此扫描构建索引数组并放弃,如果有更好的索引数组。

扫描O(n)
插入次数的计算更加复杂。
clear数(和清除的元素数)的计算也更复杂。(clear的复杂度将小于或等于删除的元素数量)

但是两者都有n的上限,所以复杂度小于或等于O(3 * n) = O(n)但也大于等于O(n)(扫描),所以它也O(n)

因此,对于这两种方法,复杂性是相同的:O(n)

对于性能计时,与往常一样,您必须进行测量。

对于第一种方法,您可以设置一个条件以将索引添加到数组中。每当最大值发生变化时,您都需要清除数组。无需迭代两次。

对于第二种方法,实现更容易。你只是发现最大第一次去。然后,您会在第二次访问中找到匹配的索引。

如之前的回答所述,在这两种情况下,复杂性均为O(n),需要采取措施来比较性能。

但是,我想补充两点:

第一个是性能比较可能取决于编译器,如何执行优化。

第二点更为关键:性能可能取决于输入数组。

例如,让我们考虑极端情况:1,1,1, .., 1, 2,即大量的1后跟一个2。使用第二种方法,您将创建一个庞大的临时索引数组,以在最后提供一个元素的数组。最后可以重新定义分配给此数组的内存大小。但是,我不喜欢创建一个临时不必要的巨大向量的想法,独立于时间性能问题。请注意,这样的阵列可能会遭受多次重新分配,这会影响时间性能。

这就是为什么在一般情况下,在没有任何输入知识的情况下,我更喜欢您的第一种方法,两次扫描。如果要实现专用于特定类型数据的函数,则情况可能会有所不同。