你会喜欢Ruby,部分原因是你通常不需要使用索引来提取或设置数组的元素。
以下是一种获得所需结果的方法。最后我将介绍一种替代计算方法,当数组很大时可以考虑使用。
代码
def pairs(arr)
arr.map { |e| e < 0 ? -e : e }.
group_by(&:itself).
select { |_,v| v.size > 1 }.
keys
end
例子
pairs [1, 8, -2, 12, -15, 5, 3]
pairs [1, 8, -2, 12, -15, 5, 3, 2, -3, 1]
如果你想让第二个例子返回 [[1, -1], [2, -2], [3, -3]]
(虽然我不知道有什么意义),将该方法的倒数第二行替换为:
map { |k,_| [k, -k] }
解释
以下是相关IT技术的步骤:
arr = [1, 8, -2, 12, -15, 5, 3, 2, -3, 1]
are:
a = arr.map { |e| e < 0 ? -e : e }
b = a.group_by(&:itself)
在Ruby v2.2中,我们得到了Object#itself。对于早期版本,请使用:
b = a.group_by { |e| e }
继续:
c = b.select { |_,v| v.size > 1 }
c.keys
这行代码:
select { |_,v| v.size > 1 }
可以编写为:
select { |k,v| v.size > 1 }
其中k
和v
代表“键”和“值”,但由于在块计算中未使用k
,因此通常将k
替换为本地变量_
(是的,它是一个变量 - 在IRB中尝试一下),主要是为了告诉读者该参数未在块中使用。
如果arr = [1, 1, -1, -1, 2, -2]
,这将返回[1,2]
。如果您希望它返回[1,1,2]
,则必须采用不同的方法。
大数组的替代计算方法
如果数组(大小为n)很大,则可以通过首先将数组转换为集合来将计算复杂度从O(n 2 )减少到几乎O(n)(“几乎”将在下面解释):
require 'set'
arr = [3, 5, -7, 4, 2, 7, -6, 1, 0]
st = arr.to_set
我们可以计算如下:
arr.find { |n| st.include?(-n) }
从数组构建集合的时间复杂度为O(n)。集合查找(st.include?(-n)
)等同于哈希查找(即计算给定键k
的h[k]
),几乎是常数时间,即O(1)。