'列出索引超出范围' in while循环旨在从列表中返回两个值,这些值将添加到特定总和

时间:2016-12-27 20:25:11

标签: python-3.5

第11行产生错误。单步执行代码并不能解决问题? 代码只是从列表的左端和右端指向,每次迭代移动指针,直到找到目标总和!看起来循环不会踩到它自己,但似乎无论如何。

def twoSum(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 = array[0]
    r = array[len(array)-1]
    indx_Dict = dict(enumerate(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

num_array1 = [2, 7, 11, 15,1,0]
target1 = 9 

twoSum(num_array1, target1)

2 个答案:

答案 0 :(得分:1)

这就是我改变了:

  • array[len(array)-1] - &gt; len(array)-1(这就是导致您的IndexError
  • 的原因
  • indx_Dict:我更改了indx_Dict[sorted_index] = original_index
  • sum - &gt; sum_sum是内置的。使用其中一个作为变量名称永远不是一个好主意! (是的,新名称可能更好)

这是最终的代码:

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

这是关于这个问题的讨论: Find 2 numbers in an unsorted array equal to a given sum(您似乎意识到这一点 - 看起来就像您要做的那样)。这是一个python版本:

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

此版本基于循环索引ij

现在这里有一个我认为更加pythonic的版本(但可能有点难以理解;但它与上面的版本完全相同)。它完全忽略了索引j,因为它并不是真正需要的:

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

aaaa只是为了它的乐趣:每当有一个排序列表在播放时我觉得需要使用bisect模块。 (一个非常基本的基准测试表明,n > 10'000'000可能表现得更好; n是列表的长度。所以对于所有实际目的而言可能不值得......)

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

(更多)完整性:有一种基于字典的方法:

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

我希望代码可以作为自己的解释......

答案 1 :(得分:0)

lr不是您的索引,而是数组中的值。

假设你有一个数组:[21,22,23,23]l为21,r为23;因此,调用array[21]是不合格的。

此外,您的indx_Dict会出现问题。您在其上调用enumerate,返回[(0,21),...(3,23)]。致电dict即可获得{0:21,1:22,2:23,3:23}。没有相当于21或23的密钥,这也会给你一个错误。

你可以尝试的是:

def twoSum(num_array, asum):
    '''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
    while (l < len(array)-1) :
        while (r > l):
            if (array[l] + array[r]) == asum:
                return [num_array.index(array[l]),\
                        num_array.index(array[r])]
            r -= 1
        r = len(array)-1
        l += 1

num_array1 = [2, 7, 11, 15,1,0]
target1 = 9 

twoSum(num_array1, target1)

这样,您的lr都是排序array的索引。它遍历数组中每个可能的值组合,并在找到总和或通过所有内容时返回。然后它返回包含正确值的原始num_array的索引。

另外,正如@ hiro-protagonist所说,sum已经是Python中的内置函数,因此应该将其更改为其他内容(在我的示例中为asum)。