2016-04-28 47 views
0

如果數組中的一對數相加爲零,我需要這兩個數的位置。如果沒有一對數字總和爲零,我應該返回nilRuby中帶有兩個循環的兩個和的總和

迭代沒有發生在我的外循環:

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 
+0

注意,你不能在'return ...'後面使用'puts'。 'puts'永遠不會被看到。另外,你可以用'j + = 1'和'i + = 1'來代替'j = j + 1'和'i = i + 1'。 –

回答

1

的問題是,你只在一開始設定的j = 1值,但是你需要它重置爲每個外迭代。只要將j = 1

while(i < l) 

甚至更​​好以後:j = i + 1

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 
+0

這很明顯,但效率相對較低,因爲它可能需要達到'nums.length * nums.length/2'計算。 –

+2

我重新表達了OP的原始邏輯。實現的選擇,對於大中型數組而言,更高效的數組對於更簡單的數組,對於更小的數組可能更快,取決於:1)輸入數組的預期大小,2)速度的重要性,3)簡單性有多重要是和4)這是一個真實的世界生產算法還是一個學術演習(我懷疑後者)。 –

+1

是的,我沒有很好地表達。如果數組不是很大,那麼效率不是問題,所以使用容易實現和理解的實現是很有意義的,這是最不可能產生錯誤的。 –

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) 
+0

我打算提出一個「組合(2)」解決方案,但我不得不問自己 - 這比@基思的簡單方法更容易閱讀。答案是否定的。 – ndn

+0

誠然,@ndn,但正如Keith所指出的那樣,對於不同的情況有不同的需求。 –