给定一个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.
答案 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处终止。