[英]How to find pairs of integers in a list that add up to a target in O(N)?
我有一個輸入列表
lst = [2, 4, 3, 6, 5]
如果我說target = 7
,我想得到
[(0, 4), (1, 2)]
這些是lst
中數字對的索引,它們加起來為target
(7)。
我們如何使用單個for
循環獲得預期結果?
這樣想:對於您遇到的索引i
處的每個數字n
,您需要找到一個包含7 - n
的索引j
。 您可以通過維護以下結構在列表中單次執行此操作:
7 - n
: i
的映射,這樣當你在索引j
處遇到7 - n
時,你可以添加對i, j
一種僅使用一個循環的簡單方法是
from collections import defaultdict
def find_target(data, target):
pairs = []
found = defaultdict(list)
for i, n in enumerate(data):
m = target - n
found[m].append(i)
if n in found:
pairs.extend((j, i) for j in found[n])
return pairs
使用defaultdict
保存所有可能重復項的索引列表是確保獲得所有可能組合的簡單方法。
對於您的具體情況:
>>> find_target([2, 4, 3, 6, 5], 7)
[(1, 2), (0, 4)]
結果按第二個索引排序(因為它決定了一對何時進入列表)。 如果要按第一個索引對其進行排序,可以這樣做:
>>> result = find_target([2, 4, 3, 6, 5], 7)
>>> result.sort()
>>> result
[(0, 4), (1, 2)]
或者更浪費,
>>> sorted(find_target([2, 4, 3, 6, 5], 7))
[(0, 4), (1, 2)]
在單個列表理解中:按目標值過濾並跳過重復值。
target = 7
lst = [2, 4, 3, 6, 5]
output = [(i1, i2) for i1, j1 in enumerate(lst) for i2, j2 in enumerate(lst) if j1+j2 == target and i1 < i2]
print(output)
或者,為了避免and
,使用切片(連同i2
-index 的移位):
[(i1, i2) for i1, j1 in enumerate(lst) for i2, j2 in enumerate(lst[i1:], start=i1) if j1+j2 == target]
作為單個for 循環。 想法:迭代所有對的“集合”的大小(不使用按距離過濾,如瘋狂物理學家的回答):
lst = [2, 4, 3, 6, 5, 1]
target = 7
out = []
n = len(lst)
blk = n-1
loop_counter = 1
c = 0
for i in range(n*(n-1)//2):
# indices
a, b = n-blk-1, c % blk + n-blk
# check condition
if lst[a] + lst[b] == target:
out.append((a, b))
# next iteration
c+=1
if c % blk == 0:
blk -= 1
c = 0
loop_counter += 1
print(out)
#[(0, 4), (1, 2), (3, 5)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.