给定一个整数数组,什么算法将返回五个最小数字的总和?我想通过一次通过而不依赖于排序算法来做到这一点。
鉴于我们不能只对输入数组进行排序并获得五个最小数字,我计划在开头存储前五个数字,然后比较其余输入并保持存储五个最小数字。但是,如何在没有排序算法的情况下获取最小的前五个?
答案 0 :(得分:1)
您可以使用selection algorithm,其中k为5.您可以将列表从头开始返回k并将所有数字相加。如果你做中位数的中位数,那就是O(n)。
此算法依赖于某些分类所依赖的相同分区例程(想想快速排序)。但是,它不会对元素进行排序。
答案 1 :(得分:1)
遍历数组并将元素放在大小为5的最大堆中。因此,最终堆中存在的元素是最小的元素,它们的总和将产生所需的答案。
对于数组中的每个元素(比如x),检查它是否小于max heap中的max元素。 如果它很小,则用x替换堆中的max元素 其他只是转到下一个元素。
最后,您将只有堆中的5个最小元素。
答案 2 :(得分:0)
在查看阵列的其余部分之前,挑选最初的五个数字并不需要你选择五个最小的数字:如果你这样做了,你就不需要查看数组的其余部分。
让我们通过为您的方法编写签名来简化这一过程:
getSmallest(array<int> input, int nSmallest) -> array<int> # length of nSmallest
这种方法必须做什么?
nSmallest
元素放入输出数组生成的输出数组将保存所有最小的元素,并且不会对任何内容进行排序。让我们写一些伪代码,从检查输出数组开始:
# returns true if the candidate was swapped in, false otherwise.
# NOTE: outputArray and candidate can be modified by this function!
# If boolean is 'true' then 'candidate' will contain the swapped out element
swapElement(array<int> outputArray, int candidate) -> boolean
foreach idx->smallNumber in outputArray
if (candidate < smallNumber) {
outputArray[idx] = candidate
candidate = smallNumber
return true
}
return false
现在我们已经处理了这个核心问题,我们如何使用该解决方案?
getSmallest(array<int> input, int nSmallest) -> array<int>
output[nSmallest] = copy(input, nSmallest) # copies the first nSmallest elements into output
# Iterate through the remainder of the list
for (idx = nSmallest, length(input), idx++) {
checkingCandidate = true
candidate = input[idx]
while (checkingCandidate){ # This ensures that swapped candidates get checked too, no matter how many
checkingCandidate = swapElement(output, candidate)
} # This will quit once we are no longer swapping elements.
}
return output
你有完整的解决方案 - 伪代码。正如您所看到的,核心问题是拥有输出数组,并在找到它时交换较小的元素(防止您首先需要对数组进行排序)。一旦你将问题减少到&x 39; x元素小于y数组中的任何内容,其余的只是迭代。哦,最后你只需在输出数组中添加所有数字 - 这应该是微不足道的。
答案 3 :(得分:-1)
您可以使用大小为5的优先级队列。比较的功能是保持头部的最大数字。
当它迭代数组时,如果size&lt;如果size = 5,则将队列的头数与其余的nums进行比较。如果array [i]&lt; queue.front() 然后弹出队列的头部,并将array [i]推入队列。
最后,队列的总和是最小的。