如何对数组中最大的两个元素求和

时间:2013-10-13 21:31:53

标签: ruby

使用Ruby获取数组中两个最大值之和的适当方法是什么?

我知道array.sortarray.max以及inject(:+),但我不知道如何将它们合并。

5 个答案:

答案 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(:+)

如果您熟悉算法复杂度,那么您可以看到第一个是nlognn^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