带有两个循环的Ruby中两个总和的总和

时间:2016-04-28 20:01:18

标签: ruby

如果数组中的一对数字总和为零,我想要那两个数字的位置。如果没有数字对总和为零,我应该返回nil

迭代没有发生在我的外循环中:

def two_sum(nums)
  # puts(nums)
  l = nums.length
  i = 0
  j = 1
  while(i < l)
    while(j < l)
      puts(nums[i] + nums[j])
      puts(nums[i])
      puts(nums[j])
      if(nums[i] + nums[j] == 0)
        return ("[" + i.to_s + "," + j.to_s + "]")
        puts("[" + i.to_s + "," + j.to_s + "]")
      else
        j = j + 1
      end
    end
    i = i + 1
  end
end

3 个答案:

答案 0 :(得分:2)

使用范围和each要简单得多;这使代码更清晰,更简洁:

#!/usr/bin/env ruby

def two_sum(nums)
  (0...nums.length).each do |i|
    ((i+1)...nums.length).each do |j|
      return [i, j] if nums[i] + nums[j] == 0
    end
  end
  nil
end

p two_sum([1, 2, 3, -1, 4])  # [0, 3]
p two_sum([1, 2, 3])         # nil
p two_sum([])                # nil

答案 1 :(得分:1)

问题是你只在开始时设置j = 1的值,但是你需要为每个外部迭代重置它。只需在

之后移动j = 1即可
while(i < l)

甚至更好:j = i + 1

答案 2 :(得分:1)

由于✅已经回答了你的问题,我想建议一个替代方案:

def pair_sums_to_zero(arr)
  h = arr.each_with_index.group_by { |n,_| n.abs }      
  return h[0].first(2).map(&:last) if h.key?(0) and h[0].size > 1
  a = h.map { |k,v| v.uniq(&:first) }.find { |b| b.size == 2 }
  a ? a.map(&:last) : nil
end

arr = [3,2,-4,-2,3,2]
pair_sums_to_zero arr
  #=> [1,3]

步骤:

  h = arr.each_with_index.group_by { |n,_| n.abs }
    #=> {3=>[[3, 0], [3, 4]], 2=>[[2, 1], [-2, 3], [2, 5]], 4=>[[-4, 2]]} 
  h.key?(0) and h[0].size > 1
    #=> false 
  c = h.map { |k,v| v.uniq(&:first) }
    #=> [[[3, 0]], [[2, 1], [-2, 3]], [[-4, 2]]]
  a = c.find { |b| b.size == 2 }
  a ? a.map(&:last) : nil
    #=> [[2, 1], [-2, 3]] 
  a ? a.map(&:last) : nil
    #=> [1, 3]       

另一个例子:

arr = [3,0,2,-4,-6,0,3,0,2]
pair_sums_to_zero arr

h = arr.each_with_index.group_by { |n,_| n.abs }    
  #=> {3=>[[3, 0], [3, 6]], 0=>[[0, 1], [0, 5], [0, 7]], 2=>[[2, 2], [2, 8]],
  #    4=>[[-4, 3]], 6=>[[-6, 4]]} 
h.key?(0) and h[0].size > 1
  #=> true 
h[0].first(2).map(&:last)
  #=> [1, 5] (returned) 
相关问题