包括副本和反向有序对,它们加起来总和
numbers = [1, 2, 4, 4, 4, 4, 5, 5, 5, 7, 7, 8, 8, 8, 9]
match = []
for i in range(len(numbers)):
for j in range(len(numbers)):
if (i!=j):
if(numbers[i] + numbers[j] == sum):
match.append([numbers[i], numbers[j]])
我需要检查匹配项和重复项,因此输出需要看起来像[[1, 9], [2, 8], [2, 8], [2, 8], [5, 5], [5, 5], [5, 5], [5, 5], [5, 5], [5, 5], [8, 2], [8, 2], [8, 2], [9, 1]]
答案 0 :(得分:0)
这是一个变种:
from collections import Counter
def sum_target(lst, target):
unique_list = list(set(lst))
counts = Counter(lst)
remainders = {number: target-number for number in unique_list}
match = set()
for a, b in remainders.items():
if b in remainders:
match.add(tuple(sorted((a, b))))
# restore multiplicities:
ret = []
for a, b in match:
if a != b:
mult = counts[a] * counts[b]
ret.extend([a, b] for _ in range(mult))
ret.extend([b, a] for _ in range(mult))
# ret.append((mult, (a, b)))
# ret.append((mult, (b, a)))
else:
mult = counts[a] * (counts[a]-1)
ret.extend([a, a] for _ in range(mult))
# if mult != 0:
# ret.append((mult, (a, b)))
return ret
并不完全确定多重性是按照你想要的方式处理的(在你的例子中它们是我得到的两倍......为什么有[5, 5]
的6个版本?你的三个5
s原始列表你只得到3双......)
如果您的列表中有许多重复项,那么根据您的输出长度,我建议将代码的最后一部分更改为
# restore multiplicities:
ret = []
for a, b in match:
if a != b:
mult = counts[a] * counts[b]
ret.append((mult, (a, b)))
ret.append((mult, (b, a)))
else:
mult = counts[a] * (counts[a]-1)
if mult != 0:
ret.append((mult, (a, b)))
获得结果
numbers = [1, 2, 4, 4, 4, 4, 5, 5, 5, 7, 7, 8, 8, 8, 9]
s = 10
print(sum_target(lst=numbers, target=s))
# [(3, (8, 2)), (3, (2, 8)), (6, (5, 5)), (1, (1, 9)), (1, (9, 1))]
答案 1 :(得分:0)
正如评论中提到的那样,对于一般情况没有O(n)
解决方案,因为在最坏的情况下,您需要输出n^2
个数字对 - 显然它不能在{{{}}中完成1次。但是当阵列中没有相同的数字时,有线性解决方案,你只需要使用字典:
O(n)
答案 2 :(得分:0)
In[50]: numbers
Out[50]: [1, 2, 4, 4, 4, 4, 5, 5, 5, 7, 7, 8, 8, 8, 9]
In[51]: expected_result
Out[51]:
[[1, 9],
[2, 8],
[2, 8],
[2, 8],
[5, 5],
[5, 5],
[5, 5],
[5, 5],
[5, 5],
[5, 5],
[8, 2],
[8, 2],
[8, 2],
[9, 1]]
In[52]: from collections import Counter
...:
...:
...: def matches(nums, target):
...: cnt = Counter(nums)
...: result = []
...: for num in nums:
...: diff = target - num
...: result.extend([[num, diff]] * (cnt[diff] - (diff == num)))
...: return result
...:
In[53]: matches(numbers, target=10) == expected_result
Out[53]: True