我已经解决了这个问题几个小时了,我无法理解为什么我无法让它正常运行。这种方法的最终游戏是在一个数组中有2个数字,当加在一起时等于零。这是我的代码:
def two_sums(nums)
i = 0
j = -1
while i < nums.count
num_1 = nums[i]
while j < nums.count
num_2 = nums[j]
if num_1 + num_2 == 0
return "There are 2 numbers that sum to zero & they are #{num_1} and #{num_2}."
else
return "Nothing adds to zero."
end
end
i += 1
j -= 1
end
end
我遇到的问题是,除非数组中的第一个和最后一个数字是相同数字的正数和负数,否则它将始终返回false。
例如,如果我有一个[1,4,6,-1,10]的数组,它应该会回来。我确定我的2声明是导致这种情况的原因,但我无法想出解决问题的方法。如果有人能指出我正确的方向,那将会有所帮助。
答案 0 :(得分:5)
您可以找到第一对加起来为0的对,如下所示:
nums.combination(2).find { |x, y| x + y == 0 }
#=> returns the first matching pair or nil
或者,如果要选择总计为0的所有对:
nums.combination(2).select { |x, y| x + y == 0 }
#=> returns all matching pairs or an empty array
因此,您可以像这样实现您的方法:
def two_sums(nums)
pair = nums.combination(2).find { |x, y| x + y == 0 }
if pair
"There are 2 numbers that sum to zero & they are #{pair.first} and #{pair.last}."
else
"Nothing adds to zero."
end
end
或者如果你想找到所有对:
def two_sums(nums)
pairs = nums.combination(2).select { |x, y| x + y == 0 }
if pairs.empty?
"Nothing adds to zero."
else
"The following pairs sum to zero: #{pairs}..."
end
end
答案 1 :(得分:3)
这是另一种方式:
<强>代码强>
def sum_to_zero(arr)
arr.group_by { |e| e.abs }
.values
.select { |a| (a.size > 1 && a.first == 0) || a.uniq.size > 1 }
end
<强>实施例强>
sum_to_zero [1, 4, 6, -1, 10] #=> [[1, -1]]
sum_to_zero [1, 4, 1, -2, 10] #=> []
sum_to_zero [1, 0, 4, 1, 0, -1] #=> [[1, 1, -1], [0, 0]]
这种方法相对较快。让我们尝试一下200,000个元素的数组,每个元素都是-500,000到500,000之间的随机数。
require 'time'
t = Time.now
arr = Array.new(200_000) { rand(1_000_001) - 500_000 }
arr.size #=> 200000
sum_to_zero(arr).size #=> 16439
Time.now - t
#=> 0.23 (seconds)
sum_to_zero(arr).first(6)
#=> [[-98747, 98747],
# [157848, -157848],
# [-459650, 459650],
# [176655, 176655, -176655],
# [282101, -282101],
# [100886, 100886, -100886]]
如果您希望将总和为零的非负值和负值分组:
sum_to_zero(arr).map { |a| a.partition { |e| e >= 0 } }.first(6)
#=> [[[98747], [-98747]],
# [[157848], [-157848]],
# [[459650], [-459650]],
# [[176655, 176655], [-176655]],
# [[282101], [-282101]],
# [[100886, 100886], [-100886]]]
如果您只需要每个组的单个值(例如非负值):
sum_to_zero(arr).map { |a| a.first.abs }.first(6)
#=> [98747, 157848, 459650, 176655, 282101, 100886]
答案 2 :(得分:2)
我认为最Ruby的方式是:
nums.combination(2).any? { |x,y| (x+y).zero? }
答案 3 :(得分:2)
这是一种适用于大型数组的方法。上面的方法经历了两个数字的每个可能的组合对于小的情况非常好,但是对于具有大量元素的数组来说将非常慢并且内存很耗力。
def two_sums nums
h = Hash.new
nums.each do |n|
return true if h[-n]
h[n] = true
end
false
end
答案 4 :(得分:1)
好吧,鉴于它标记为#ruby,这里有最多&#34;红宝石的方式&#34;我能想到解决这个问题:
def two_sums(arr)
numbers = arr.combination(2).select { |a| a.reduce(:+) == 0 }.flatten
if numbers.empty?
"Nothing adds to zero."
else
"There are 2 numbers that sum to zero & they are #{numbers.first} and #{numbers.last}."
end
end
答案 5 :(得分:0)
array.combination(2).select{|x|x[0] + x[1] == 0}