使用Ruby获取数组中两个最大值之和的适当方法是什么?
我知道array.sort
和array.max
以及inject(:+)
,但我不知道如何将它们合并。
答案 0 :(得分:6)
我强烈赞成更简单,更快捷:
array.max(2).reduce(:+)
排序是不必要的,只需扫描数组就可以更新大小为K的最大堆。使用Array#max(K)
可以实现O(N x log(K))渐近时间复杂度与O(N x log( N))排序。
答案 1 :(得分:4)
[9, 4, 5, 1].sort.last(2).sum
=> 14
答案 2 :(得分:2)
[1,2,3,4].sort[-2..-1].inject(:+)
如果您正在寻找更有效的解决方案,那么您将会更好:
[1,2,3,4].inject([0, 0]) do |largest, el|
if largest[0] < el
largest[1] = largest[0]
largest[0] = el
elsif largest[1] < el
largest[1] = el
end
largest
end.inject(:+)
如果您熟悉算法复杂度,那么您可以看到第一个是nlogn
到n^2
,这取决于Ruby排序算法,其中第二个解决方案只是n
因为它通过阵列一次。
答案 3 :(得分:1)
你可以试试这样的事情
array = [13, 2, 21, 36, 4, 9]
array.reverse.first(2).reduce(:+)
在这个方法中,我们对数组进行反向排序,即从最高到最低排序。这将最大数字放在数组中。 reduce
方法返回这些数字的总和。在这种情况下,36和21之和为57。
57
答案 4 :(得分:1)
总而言之,有一些基准来看看实现目标的最快方法是什么:
require 'active_support/core_ext/enumerable'
require 'fruity'
ARRAY = (0..1000).to_a.shuffle
compare do
adriano { ARRAY.max(2).reduce(:+) }
mori { ARRAY.sort.last(2).sum }
edgars { ARRAY.sort[-2..-1].inject(:+) }
end
# >> Running each test 64 times. Test will take about 1 second.
# >> adriano is faster than edgars by 50.0% ± 10.0%
# >> edgars is similar to mori