我正在编写一个函数,给定一个numbers
和一个target_sum
的列表,返回基于零的索引任何两个不同的元素,其总和等于目标总和。如果没有这样的元素,函数应该返回(-1,-1)。
这是我提出的解决方案:
class TwoSum:
@staticmethod
def find_two_sum(numbers, target_sum):
"""
:param numbers: (list of ints) The list of numbers.
:param target_sum: (int) The required target sum.
:returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
"""
numbers = list(sorted(numbers)) # added after the update
# to make sure numbers are always sorted
lo_index = 0
hi_index = len(numbers) - 1
while lo_index < hi_index:
pair_sum = numbers[lo_index] + numbers[hi_index]
if pair_sum < target_sum:
lo_index += 1
elif pair_sum > target_sum:
hi_index -= 1
else:
return (lo_index, hi_index)
return (-1, -1)
print(TwoSum.find_two_sum([1, 3, 5, 7, 9], 12)) # I assume the list is already sorted
我在testdome发现了这个挑战,我想知道为什么这个代码在最后一次测试时失败了Performance test with a large number of elements: Wrong answer
。我目前正在进行招聘测试,并认为这个解决方案已经足够好了。
更新
我想我提出的解决方案完全没问题。我只想在我的机器上添加执行时间,以获得目前为止给出的答案。我在评论中提到了我的函数numbers = list(sorted(numbers))
。
>>> timeit.timeit(lambda: find_two_jdehesa([1, 3, 5, 7, 9], 12))
3.0298462831085544
>>> timeit.timeit(lambda: find_two_delirious_lettuce([1, 3, 5, 7, 9], 12))
1.6323729552793793
>>> timeit.timeit(lambda: find_two_op([1, 3, 5, 7, 9], 12))
1.23889097157587
更新2:
import random
>>> timeit.timeit(lambda: find_two_jdehesa(random.sample(range(1, 1000), 500), random.randint(1, 999)), number=10000)
8.197637722340914
>>> timeit.timeit(lambda: find_two_delirious_lettuce(random.sample(range(1, 1000), 500), random.randint(1, 999)), number=10000)
5.175919267269819
>>> timeit.timeit(lambda: find_two_op(random.sample(range(1, 1000), 500), random.randint(1, 999)), number=10000)
6.3352265931093825
答案 0 :(得分:4)
这是我对LeetCode的两个求和问题的解决方案(修改后适合你的类),但它应该在这里工作:
class TwoSum:
@staticmethod
def find_two_sum(numbers, target_sum):
seen = {}
for i, num in enumerate(numbers):
try:
return (seen[num], i)
except KeyError:
seen[target_sum - num] = i
return (-1, -1)
答案 1 :(得分:1)
您的解决方案基本上没问题,但您没有考虑输入可能没有排序,因此您必须先对其进行排序并跟踪排序的索引,以便稍后返回正确的索引值:< / p>
class TwoSum:
@staticmethod
def find_two_sum(numbers, target_sum):
"""
:param numbers: (list of ints) The list of numbers.
:param target_sum: (int) The required target sum.
:returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
"""
# Sort numbers and get sorted indices
numbers, idx = map(list, zip(*sorted(zip(numbers, range(len(numbers))))))
if len(numbers) < 2:
return (-1, -1)
i = 0
j = len(numbers) - 1
while i < j:
s = numbers[i] + numbers[j]
if s == target_sum:
# Return indices from the unsorted list
return (idx[i], idx[j])
elif s < target_sum:
i += 1
elif s > target_sum:
j -= 1
return (-1, -1)
print(TwoSum.find_two_sum([1, 3, 5, 7, 9], 12))
答案 2 :(得分:0)
我在测试圆顶上进行测试。它满足大数据以外的所有要求
def find_two_sum(numbers, target_sum):
"""
:param numbers: (list of ints) The list of numbers.
:param target_sum: (int) The required target sum.
:returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
"""
i = 0
j = len(numbers) - 1
while i < j:
if numbers[i] + numbers[j] == target_sum:
return (i, j)
if numbers[i] + numbers[j] < target_sum:
i += 1
else:
j -= 1
return None
print(find_two_sum([3,1,5,7,7,5,9],10))
答案 3 :(得分:0)
根据testDome提供的提示:
提示1:嵌套的for循环可以遍历列表并以O(N ^ 2)时间计算总和。
提示2:可以使用dict来存储预先计算的值,这可能允许具有O(N)复杂度的解决方案。
我有以下解决方案:
def find_two_sum(numbers, target_sum):
taken = {}
for i, num in enumerate(numbers):
diff = target_sum - num
if diff in taken:
return i, taken[diff]
taken[num] = i
my_list = [3, 1, 5, 7, 5, 9]
print(find_two_sum(my_list, 10))
我得到以下结果:
Run OK
(3, 0)
Your score is 100%, perfect!