我正在编写一个方法的代码,该方法返回在Zero中添加结果的索引对的总和。我已经想到了一切,但是,我遇到了一个我无法找到的错误并且让我疯狂!
传递array = [-1, 0, 2, -2, 1].two_sum
(我的方法)时,返回值为[[0, 4], [1, 1], [2, 3]]
而不是[[0, 4], [2, 3]]
(该方法在末尾对arr进行排序)。出于某种原因,我的方法是两次使用idx 1
,尽管我认为我已在代码中指定我只想比较idx
和idx + 1
。
我的代码出了什么问题?
这是我到目前为止所做的:
class Array
def two_sum
final_arr = []
self.each_with_index do |each, idx|
self.each_index do |comp_idx|
unless comp_idx + 1 == self.length || idx == comp_idx
if (each + self[comp_idx + 1]) == 0
final_arr << [idx, comp_idx + 1].sort
end
end
end
end
final_arr.sort
end
end
感谢您的帮助!
答案 0 :(得分:2)
此代码非常难以理解/维护。无论如何,有两个问题:
idx == comp_idx
执行任何操作,然后比较idx
和comp_idx + 1
[2, 3]
和[3, 2]
会泄漏到结果中。以下是更正后的版本:
class Array
def two_sum
final_arr = []
self.each_with_index do |each, idx|
self.each_index do |comp_idx|
# ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
unless comp_idx + 1 == self.length || idx == comp_idx + 1
if (each + self[comp_idx + 1]) == 0
final_arr << [idx, comp_idx + 1].sort
end
end
end
end
# ⇓⇓⇓⇓⇓
final_arr.sort.uniq
end
end
Bonus track:更多惯用的ruby版本。
▶ arr.each.with_index.with_object([]) do |(e1, idx1), result|
result <<
([idx1].product(
arr[idx1 + 1, arr.length]. # compare only not yet compared
each.
with_index(idx1 + 1). # adjust index
select { |e2, idx2| (e1 ^ -e2).zero? }
))
end.flatten(1).map { |i1, (_, i2)| [i1, i2] }
#⇒ [[0, 4], [2, 3]]
答案 1 :(得分:0)
如果您对简单和rubyist的内容感到满意,可以尝试
arr = [-1, 0, 2, -2, 1]
[*0...arr.size].combination(2).to_a.each_with_object([]) do |a, final_arr|
final_arr << a if arr[a[0]]+arr[a[1]] == 0
end
final_arr.sort
答案 2 :(得分:0)
由于您的代码问题已经确定,我只会建议一种不同的,更有效的方法来计算所需的索引对。
<强>代码强>
def two_sum(arr)
hneg = Hash.new { |h,k| h[k] = [] }
hpos = Hash.new { |h,k| h[k] = [] }
azero = []
arr.each_index do |i|
n = arr[i]
case n <=> 0
when -1 then hneg[-n] << i
when 1 then hpos[n] << i
else azero << i
end
end
(hneg.keys & hpos.keys).each_with_object(azero.combination(2).to_a) { |k,a|
hneg[k].product(hpos[k]) { |pair| a << pair } }
end
<强>实施例强>
two_sum [3, -1, 0, 1, 4, 0, -4, 0, 1]
#=> [[2, 5], [2, 7], [5, 7], [1, 3], [1, 8], [6, 4]]
two_sum [3, -1, 0, 1, 4, 0, -4, 0, -2, -4, 5, 4]
#=> [[2, 5], [2, 7], [5, 7], [1, 3], [6, 4], [6, 11], [9, 4], [9, 11]]
如果[i,j]
是返回的数组的元素,则arr[i] == arr[j] == 0
或arr[i] < 0
和arr[j] == -arr[i]
。如果希望用i < j
写入对,只需写下以下内容即可。
arr = [3, -1, 0, 1, 4, 0, -4, 0, -2, -4, 5, 4]
two_sum(arr).map { |pair| pair.first > pair.last ? pair.reverse : pair }
#=> [[2, 5], [2, 7], [5, 7], [1, 3], [4, 6], [6, 11], [4, 9], [9, 11]]
<强>解释强>
步骤如下。
arr = [3, -1, 0, 1, 4, 0, -4, 0, 1]
hneg = Hash.new { |h,k| h[k] = [] }
#=> {}
hpos = Hash.new { |h,k| h[k] = [] }
#=> {}
azero = []
arr.each_index do |i|
n = arr[i]
case n <=> 0
when -1 then hneg[-n] << i
when 1 then hpos[n] << i
else azero << i
end
end
#=> [3, -1, 0, 1, 4, 0, -4, 0, 1]
我们刚刚创建了以下哈希和数组。
hneg
#=> {1=>[1], 4=>[6]}
hpos
#=> {3=>[0], 1=>[3, 8], 4=>[4]}
azero
#=> [2, 5, 7]
这告诉我们arr[1] #=> -1
的{{1}},arr[6] #=> -4
,arr[0] #=> 3
,arr[3] == arr[8] #=> 1
,arr[4] #=> 4
和arr[i] #=> 0
。接着,
i = 2, 5, 7
这表明common_keys = hneg.keys & hpos.keys
#=> [1, 4]
和hneg
的公共密钥是hpos
。 (我们不必担心其他密钥。)
现在计算映射到[1, 4]
的所有索引对。
[0, 0]
最后,我们按如下方式获得所需的索引对。
zero_matches = azero.combination(2).to_a
#=> [[2, 5], [2, 7], [5, 7]]
请注意,当公共密钥为common_keys.each_with_object(zero_matches) { |k,a|
hneg[k].product(hpos[k]) { |pair| a << pair } }
#=> [[2, 5], [2, 7], [5, 7], [1, 3], [1, 8], [6, 4]]
时,
k => 1
如果有k = 1
hneg[k].product(hpos[k])
#=> [[1, 3], [1, 8]]
和hneg[1] #=> [1, 2]
,我们就会获得
hpos[1] #=> [3, 4]
查看带有默认块的类方法Hash::new的表单,Integer#<=>,Array#each_index,Array#combination和Array#product以及Enumerable#each_with_object
答案 3 :(得分:-1)
这是使用组合和选择
的其他工作解决方案class Array
def two_sum
c = (0 .. count-1).to_a.combination(2).to_a
c.select do |i,j|
self[i]+self[j] == 0
end
end
end
a = [-1, 0, 2, -2, 1]
a.two_sum