zero_sum的方法效率?(数组)#basic Ruby语言训练营入口准备

时间:2016-11-25 15:08:21

标签: ruby

我正在通过单行解决方案来解决问题#write a boolean function zero_sum?它接受一个整数数组,如果数组中的2个元素总和为零,则返回true。

这是我的原始答案,如果他们要求返回指标,也会有效,但我无法想出一个有效的单行功能。

def zero_sum?(array)
  array.each_with_index do |x, i1|
    for i2 in i1 + 1..array.length - 1
      if x + array[i2] == 0
        return true
      end
    end
  end

  false
end

puts "\nZero Sum:\n" + "*" * 15 + "\n"
puts zero_sum?([1, -1]) == true
puts zero_sum?([1,1,0,2,1]) == false
puts zero_sum?([1,1,0,2,1,0]) == true
puts zero_sum?([2,3,4,-3,1]) == true

这是我的一线解决方案。我根本没有得到任何错误的回报:

def zero_sum?(array)
  array.any? {|x| array.each {|y| array.count(0) != 1 && x + y == 0}}
end

puts "\nZero Sum:\n" + "*" * 15 + "\n"
puts zero_sum?([1, -1]) == true
puts zero_sum?([1,1,0,2,1]) == false  #returning true 
puts zero_sum?([1,1,2,1]) == false  #returning true
puts zero_sum?([1,1,0,2,1,0]) == true
puts zero_sum?([2,3,4,-3,1]) == true

任何见解都会很棒! (如果想到返回指数的单行响应,那就太棒了!)。

4 个答案:

答案 0 :(得分:1)

试试这个。

require 'set'

def zero_sum?(arr)
  arr.each_with_object(Set.new) do |n,st|
    return true if st.include?(-n)
    st << n
  end
  false
end

zero_sum? [1,-1]        #=> true
zero_sum? [1,1,0,2,1]   #=> false
zero_sum? [1,1,0,2,1,0] #=> true
zero_sum? [2,3,4,-3,1]  #=> true

我已经使st成为一个集而不是数组来加速查找。

答案 1 :(得分:0)

使用Array#combination执行此操作的一种方法:

def zero_sum? arr
  arr.combination(2).any? { |pair| pair.inject(:+).zero? }
end

zero_sum? [2,3,5,2,1,-2,4]    #=> true
zero_sum? [2,3,5,2,1,2,4]     #=> false
zero_sum? [2,3,5,0,0,2,1,2,4] #=> true

关于这个答案的警告是Array#combination是昂贵的,所以可能有更好的方法。但有趣的是要知道这种方法。

非常感谢@Ursus指出使用any?代替find

答案 2 :(得分:0)

您的单行解决方案的问题在于,如果先前未找到零和,则any?each循环遍历整个数组,则每个元素将在某些元素处添加到自身点。这意味着如果数组包含0,您将得到0 + 0 == 0比较。

我不会破坏为您找到一个衬垫,但是如果您想找到一个类似于您的多线解决方案的解决方案,那么您可以获得当前元素的索引,同时仍然使用{{1通过创建any并使用Enumerator

来创建
with_index

您可以使用切片表示法访问数组的其余部分:

array.to_enum.with_index.any? { |x, index| ... }

答案 3 :(得分:0)

虽然不是单行,但另一种方法是使用Enumerable#partition并行分配来获得两个数组,数字列表arr的正数和负数。

def zero_sum? arr
  return true if arr.count(0) > 1
  a, b = arr.uniq.partition(&:positive?)
  a.any? { |e| b.include? -e }
end

zero_sum? [2,3,5,2,1,-2,4]    #=> true
zero_sum? [2,3,5,2,1,2,4]     #=> false
zero_sum? [2,3,5,0,0,2,1,2,4] #=> true

其他关键方法:Numeric#positive?Array#any?Array#include?