Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 计算列表中k个最大数之和的有效方法?_Arrays_Algorithm_List_Data Structures - Fatal编程技术网

Arrays 计算列表中k个最大数之和的有效方法?

Arrays 计算列表中k个最大数之和的有效方法?,arrays,algorithm,list,data-structures,Arrays,Algorithm,List,Data Structures,我在读一些练习面试的问题,我有一个关于这个的问题。假设一个随机整数列表,每个都在1到100之间,计算k个最大整数的和?讨论空间和时间复杂度,以及如果每个整数在1和m之间(其中m变化),方法是否会改变 我的第一个想法是对数组排序并计算最大k个数的和。然后,我想如果我使用二叉树结构,我可以从右下角的树开始看。我不确定我的方法是否会改变数字是1到100还是1到m?最有效的方法是什么?最有效的方法可能是使用类似的方法。它不执行排序步骤直到完成,而是执行快速排序中的分区步骤。如果你不想让k个最大的整数以某

我在读一些练习面试的问题,我有一个关于这个的问题。假设一个随机整数列表,每个都在1到100之间,计算k个最大整数的和?讨论空间和时间复杂度,以及如果每个整数在1和m之间(其中m变化),方法是否会改变


我的第一个想法是对数组排序并计算最大k个数的和。然后,我想如果我使用二叉树结构,我可以从右下角的树开始看。我不确定我的方法是否会改变数字是1到100还是1到m?最有效的方法是什么?

最有效的方法可能是使用类似的方法。它不执行排序步骤直到完成,而是执行快速排序中的分区步骤。如果你不想让k个最大的整数以某种特定的顺序排列,这就是我的选择。这需要线性时间,但分析不是很简单。m对这一点影响不大。此外,您还可以编写代码,这样可以在分区数组时计算和

Time: O(n)
Space: O(1)

另一种选择是使用具有线性时间保证的排序。正如您所说,这些值是固定范围内的整数,它将非常有效。随着m的增加,空间需求增加,但是在桶中计算和是非常有效的

Time: O(m) in the worst case (see comments for the argument)
Space: O(m)

我想说排序可能是不必要的。如果
k
很小,那么您需要做的就是维护一个排序列表,该列表将截断
k
第四大元素之外的元素


在添加的元素最大化的最坏情况下,此步骤中的每个步骤都应为
O(k)
。然而,一般情况下的情况要好得多,在一定数量的元素之后,大多数元素应该只比列表中的最后一个元素小,并且操作将是
O(log(k))

一种方法是使用最大大小为k的()。查看新元素是否属于堆只是O(1),因为它是一个最小堆,而检索最小元素是一个常数时间操作。沿O(n)列表的每个插入步骤(如果元素太小而无法插入,则为非插入步骤)都是O(log k)。最后一个树遍历和求和步骤是O(k)

总复杂性:

O(n对数k+k)=O(n对数k)


除非您的计算机上运行多个内核(在这种情况下,并行计算是一种选择),否则只能在最后进行求和。动态计算增加了额外的计算步骤,但实际上根本没有降低时间复杂度(实际上,您将有更多的计算要做)。无论如何,您都必须对k个元素求和,所以为什么不避免额外的加减步骤?

“在一定数量的元素之后,大多数元素应该比列表中的最后一个元素小”——我不太明白这是怎么回事。即使在一般情况下,它们也是随机数。另外,您建议在k长度列表上使用什么排序策略?您不需要排序。只需运行二进制搜索以查找数组中下一个元素的位置,然后将所有剩余内容向右移动,丢弃最后一个元素并将新元素插入它所属的位置。经过一定次数的迭代后,大部分时间不需要移动,因为最低元素将高于随机样本中的平均元素。我明白了。你所描述的听起来很像。@Anirudhramana谢谢。我知道我描述的东西可能有一个名字,但我不知道。如果我用BST做这个,我会平均看nlog(n)吗?是的,我想是的。假设您构造了一个平衡的二叉搜索树结构,每次插入大约需要O(logn),并且在构建之后,您必须对整个子树求和。堆比上述解决方案更合适,但更复杂。在计数排序方案中,时间复杂度不应该是O(n+m)吗?@EyalSchneider我们查看每个元素(其中n个),并将它们放入适当的第m个桶中。不过,我不知道m在时间计算中会起什么作用。稍后,我们最多读取k个桶,k严格小于n。@AnirudhRamanathan:在第二阶段,从最高的桶开始扫描m个桶。但是,其中许多可能包含0个计数,因此在最坏的情况下,您必须扫描所有m个存储桶。这是否与使用优先级队列来保存K个最大数字的列表具有类似的复杂性“虽然优先级队列通常使用堆来实现,但它们在概念上与堆不同。优先级队列是一个抽象概念,如“列表”或“映射”;正如列表可以用链表或数组实现一样,优先级队列也可以用堆或各种其他方法(如无序数组)实现。“是的,它的复杂性与优先级队列的常见实现相同。@Shashank您需要使用最小堆。假设1,2,3,4,5是数字,你需要找到两个最大数字的和。我的初始最小堆包含1,2当我读取3时,我删除1并插入3,现在我的堆变成2,3。当我读4时,我删除2,然后插入4。现在我的堆是3,4。@Sandeep嘿,你说得对。使用最小堆,比较步骤仅为O(1),以查看下一个元素是否属于堆。基本上,我们将堆最大化为大小k,因此插入是平均的O(logk),使用二叉树实现(最坏情况:O(n))。我理解你的观点,我已经改正了。谢谢。:)