Ruby数组 - 是否有任何元素左边的元素总和等于右边元素的总和?

时间:2014-11-11 18:50:01

标签: ruby arrays

给定一个Ruby数组,我需要找出是否存在一个元素,其中元素左边的元素总和等于它右边元素的总和。

实施例

[1,2,3,3]

元素是3,因为3 [1,2]左边的元素之和等于3右边元素的总和。

我不知道如何解决这个问题,但我会试一试。

def left_equal_right(array)
  array.any? do |x|
    index = array.index(x)
    array[0..index-1].inject(:+) == array[index+1..-1].inject(:+)
  end
end

array.any?([1,2,3,3])
=> returns true, but I'm not sure this method works for larger arrays.

4 个答案:

答案 0 :(得分:5)

这应该是最快的,因为它不会在每次迭代时对整个数组求和:

def left_equal_right ary
  left = 0
  right = ary.reduce(:+)

  ary.each do |x|
    right -= x
    return true if left == right
    left += x
  end

  false
end

在我的虚拟机上,它会在2秒内检查一个1000万个元素阵列。

答案 1 :(得分:3)

适用于长度为10,000(仅几秒钟)的数组

对于长度为100,000的阵列超时

left_equal_right (1..100_000).to_a
# =Execution timed out.

但是,如果您按以下方式修改代码:

def left_equal_right(array)
  array.any? do |x|
    index = array.index(x)

    left_sum = 0
    right_sum = 0
    left_index = 0
    right_index = 0
    while left_index < index
      left_sum += array[left_index]
      left_index += 1
    end

    while right_index < array.count
      right_sum += array[right_index]
      right_index += 1
    end
    return left_sum == right_sum
  end
end

然后你可以处理更大的数组,我尝试了1000万:

left_equal_right (1..10_000_000).to_a
# ==> false

答案 2 :(得分:3)

试试这个 - 获取索引的更好方法:

array.each_index.any? do |i|
  array[0..i-1].inject(:+) == array[i+1..-1].inject(:+)
end

这仍然会做很多不必要的重复工作,但它可以完成工作,并通过Array#index避免解决方案引入的问题。

答案 3 :(得分:1)

这与@ Max的解决方案类似,但是当阵列中的所有元素都是非负数时,我可以提前终止搜索。这是因为当一个步进数组时,右和和左和之间的差异将单调递减。

我的回答是假设每一侧必须至少有一个元素,但当然可以修改它以允许一侧有零元素。

<强>代码

def balance(arr)
  return nil if arr.size < 3
  all_non_neg = (arr.min >= 0)
  enum = arr.to_enum
  last = enum.next
  diff = arr.reduce(:+)-last
  (1..arr.size-2).each do |i|
    val = enum.next
    diff += -last - val
    return i if diff.zero?
    return -i if all_non_neg && diff < 0
    last = val
  end
  nil
end

这里,当搜索提前终止时,我返回索引的负数。这只是为了说明目的; nil会更合适。

<强>实施例

balance [1,1,1,1,1]                 #=> 2
balance [-1,-1,-1]                  #=> 1
balance [3,4,-6,7,5,-6,4,3,5,2]     #=> 4
balance [3,4,-6,7,5,-6,4,3,5,2,4,7] #=> nil
balance [3,7,2,28,6,5,8,7]          #=> 1
balance [3,7,2,28,6,5,8,7]          #=> -4

如上所述,在最后一个例子中,搜索在索引4处终止。