我需要编写一个程序来确定给定列表中是否存在两个整数a
和b
,例如a + b = c
。输入将是一个列表和整数c
。可能是a == b
,但是a
在这种情况下必须在列表中出现两次。运行时间必须在O(n*log(n))
中。
我已经尝试实现二进制搜索,但是由于必须为此对列表进行排序,因此如果不对列表进行排序,它将无法正常工作,因为排序至少需要O(n*log(n))
时间。我试图实现合并排序而不在最后合并,而只是得到a
和b
,但是我不知道这是否是死胡同。您什至会开始使用什么方式?运行时间不要超过O(n*log(n))
,这一点非常重要。
答案 0 :(得分:1)
就地排序可以在O(n log(n))
时间内完成。随后的搜索也可以在O(n)
时间内完成,因此总共O(n log(n))
。数据排序后,对于数组的每个元素a
,请使用另一端的同时搜索来检查c - a
是否也在数组中。您将以这种方式精确地遍历整个数组。 @RockyLi建议使用此方法。它具有使用O(1)
附加内存的优点:输入列表需要就地排序。
如果可以使用O(n)
附加内存,则可以遵循@PatrickHaugh's suggestion。创建一个集合。将列表中的每个元素a
添加到集合中。如果c - a
已在集合中,则返回True
。这需要O(n)
时间来完成(一次通过),并且没有排序。但这可能会使您使用的内存量增加一倍以上。
以下是玩具的实现方式:
O(1)空间,O(n log(n))时间
def has_sum(lst, c):
lst.sort()
rev = reversed(lst)
end = next(rev)
for item in lst:
while end > c - item:
end = next(rev)
if end == c - item:
return True
if item > end:
return False
O(n)空间,O(n)时间
def has_sum(lst, c):
found = set()
for item in lst:
if c - item in found:
return True
found.add(item)
return False