例如,我有一个未排序的整数数组
array = [ 2,5,3,6,33,11,7,23,8,50,9 ]
通过最小的迭代,如何找到两个总和为10的元素?
方法1:我认为
我尽力找到最好的方法,但没有任何解决办法。
答案 0 :(得分:6)
通过记住每个值上我们遗漏的金额,您可以使其近似O(n):
<div>
<ul>
<li><span class="disc"></span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse in pretium mauris. Aliquam ultrices ipsum sit amet auctor porta. Donec et metus quis dolor dignissim euismod non a sem. Sed accumsan risus quis ipsum pellentesque, quis dictum metus porttitor.</li>
<li><span class="disc"></span>Etiam et interdum ipsum, quis venenatis augue. Sed euismod, sem eget tristique molestie, arcu massa scelerisque nunc, eget scelerisque elit sem vitae nulla.</li>
<li><span class="disc"></span>Nulla id</li>
<li><span class="disc"></span>Nam ut</li>
</ul>
</div>
我们还可以使用Set,它具有相同的基本流程:
def foo(array, target = 10)
h = {}
array.each do |value|
return [h[value], value] if h.key?(value)
h[target - value] = value
end
nil
end
foo([ 2,5,3,6,33,11,7,23,8,50,9 ], 10)
=> [3, 7]
这两个选项在后台具有相同的成本(因为Ruby的Set在Hash之上实现);我更喜欢记住我们仍然需要哪个值[以及附带的哪个原始值]的语义,但是取决于您找到哪个更好地阅读。
另一种选择是使用require "set"
def foo(array, target = 10)
seen = Set.new
array.each do |value|
return [target - value, value] if seen.include?(target - value)
seen << value
end
nil
end
foo([ 2,5,3,6,33,11,7,23,8,50,9 ], 10)
=> [3, 7]
打开-这意味着计算机将进行更多(尽管仍然是线性的)工作(因为它将整个数组转换为集合,而不是仅将元素转换为集合,直到找到一个匹配),但使代码更易于阅读,因为循环只有一项工作:
array.to_set
请注意,它找到了另一个匹配项-先前的算法返回了第一个匹配项以显示其第二个数字;新的将返回第一个匹配项,并显示第一个数字。
答案 1 :(得分:3)
array.combination(2).find { |a,b| a+b == 10 }
#=> [2, 8]
如果没有两个元素合计为nil
,将返回 10
。例如,
array.combination(2).find { |a,b| a+b == 1000 }
#=> nil
这是另一种方式。
def find_pair(arr, tot)
if tot.even?
half = tot/2
return [half, half] if arr.count(half) > 2
end
a = arr.uniq.sort
p = a.find { |n| a.bsearch { |m| m >= tot-n } }
p ? [tot-p, p] : nil
end
find_pair(array, 10)
#=> [8, 2]
答案 2 :(得分:1)
我可以建议一个更详细的嵌套循环,其中数组不包含负值:
def find_elements(array, sum)
array.each_with_index do |x, ix|
next if x > sum
array.each_with_index do |y, iy|
next if ix == iy || y > sum
return [x, y] if x + y == sum
end
end
nil
end
如果有大套,是否更快?
编辑:在我的基准测试之后,速度与mattewd中的解决方案相当。例如100000.times{array << rand(0..100)}
。它会返回另一对加数。