2和算法实现的正确性

时间:2016-09-24 22:42:27

标签: python algorithm python-2.7

传统的两和​​问题(我的下面的参考实现)是,对于排序的数组,找到所有数字对,其总和值等于给定的目标值。传统实现从数组的两端进行扫描,如果当前总和小于目标值,则增加低索引指针,如果当前总和大于目标值,则减少高索引指针。

我的问题是,是否有证据证明此算法的正确性,表明它不会错过一对?

顺便说一句,如果我的代码有问题,请随时指出。

def twoSum(numbers, skipIndex, targetValue):
    i = 0
    j = len(numbers) - 1
    result = []
    while i < j:
        if i in skipIndex:
            i+=1
        if j in skipIndex:
            j+=1
        if numbers[i] + numbers[j] == targetValue:
            result.append((numbers[i], numbers[j]))
            i += 1
            j -= 1
        elif numbers[i] + numbers[j] > targetValue:
            j -= 1
        else:
            i += 1

    return result

if __name__ == "__main__":
    numbers = [1,2,4,5,6,7,9,10]
    print twoSum(numbers, [1], 11) # output, [(1, 10), (4, 7), (5, 6)]
    print twoSum(numbers, [], 11) # output, [(1, 10), (2, 9), (4, 7), (5, 6)]

1 个答案:

答案 0 :(得分:0)

让我们简化问题以找到第一个这样的对,而不是所有对(将其扩展到加在一起targetValue的所有对中很简单)。

每当增加左指针i时,您就不再考虑相应的元素,因为与数组中的 any 其他元素相加时,总和仍然太小。因此它是不可用的。对于递减右指针j,也有类似的论点,但要进行调整,即总和太大而不是太小。

另一种查看方式是,如果您认为修改指针与修改(排序的)列表相同,因为实际上与删除最小和最大的元素相同。

最后,如果指针越过,这与列表变得太小(<2个元素)而无法继续搜索是一样的。

我上面描述的是针对搜索符合targetValue的第一对的情况。要找到所有这样的对,只要指针不交叉就可以继续搜索(而不是从当前的成对和中找到targetValue时返回)。您已经完成了while i < j条件的操作(尽管对我个人而言,i != j更容易理解)。

我不确定skipIndex的实用程序在您的实现中是什么(调试代码?),但是j += 1对我来说感觉很可疑。

为进一步阅读,我写了一篇博客文章:https://funloop.org/post/2020-12-05-twosum-problem-explained.html。我不擅长数学,所以这不是一个数学解释。