that is what i changed:
array[len(array)-1]
-> len(array)-1
(that's what caused your IndexError
)
indx_Dict
: i changed it such that indx_Dict[sorted_index] = original_index
sum
-> sum_
: sum
is a built-in. it is never a good idea to use one of those as variable name! (yes, the new name could be better)
this is the final code:
def two_sum(num_array, sum_):
'''1.twoSum
Given an array of integers, return indices of the two numbers that
add up to a specific target.
'''
array = sorted(num_array)
l = 0
r = len(array)-1
indx_Dict = {array.index(val): index for index, val in enumerate(num_array)} ##
while (l < r) :
if (array[l] + array[r]) == sum_:
return [indx_Dict[l], indx_Dict[r]]
elif array[l] + array[r] < sum_:
l += 1
else:
r -= 1
here is a discussion about this problem:
Find 2 numbers in an unsorted array equal to a given sum (which you seem to be aware of - looks like what you are trying to do). this is a python version of just that:
def two_sum(lst, total):
sorted_lst = sorted(lst)
n = len(lst)
for i, val0 in enumerate(sorted_lst):
for j in range(n-1, i, -1):
val1 = sorted_lst[j]
s = val0 + val1
if s < total:
break
if s == total:
return sorted((lst.index(val0), lst.index(val1)))
return None
this version is based on looping over the indices i
and j
.
now here is a version that i feel is more pythonic (but maybe a little bit harder to understand; but it does the exact same as the one above). it ignores the index j
completely as it is not really needed:
from itertools import islice
def two_sum(lst, total):
n = len(lst)
sorted_lst = sorted(lst)
for i, val0 in enumerate(sorted_lst):
for val1 in islice(reversed(sorted_lst), n-i):
s = val0 + val1
if s < total:
break
if s == total:
return sorted((lst.index(val0), lst.index(val1)))
return None
aaaaand just for the fun of it: whenever there is a sorted list in play i feel the need to use the bisect
module. (a very rudimentary benchmark showed that this may perform better for n > 10'000'000
; n
being the length of the list. so maybe not worth it for all practical purposes...)
def two_sum_binary(lst, total):
n = len(lst)
sorted_lst = sorted(lst)
for i, val0 in enumerate(sorted_lst):
# binary search in sorted_lst[i:]
j = bisect_left(sorted_lst, total-val0, lo=i)
if j >= n:
continue
val1 = sorted_lst[j]
if val0 + val1 == total:
return sorted((lst.index(val0), lst.index(val1)))
else:
continue
return None
for (a bit more) completeness: there is a dictionary based approach:
def two_sum_dict(lst, total):
dct = {val: index for index, val in enumerate(lst)}
for i, val in enumerate(lst):
try:
return sorted((i, dct[total-val]))
except KeyError:
pass
return None
i hope the code serves as its own explanation...