leetcode中第一题twosum问题解答算法的可行性证明
一、引入
关于leetcode中第一题twosum问题,网上已有不少高人做出过解答,并提出了切实可行的算法实现。我在解答该题时参考了博客http://www.zixue7.com/article-9576-1.html的解答。为让读者更直观地阅读和理解本文,先简要摘录以上博客的内容如下:
- 题目还原
Two Sum
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
中文意思就是给你一个整数数组和一个目标值,找出这个数组中的两个元素的和为该目标值的元素的下标,输出为index1和index2,按从小到大的序输出。且假定每个数组都恰好包含一个解,即使,恰好每个给定的数组都有且只有一种符合的结果。
- 解答
首先,做这种的题目一般都是需要排序的,为了速度,也为了方便查找。
当然,不排序也可以做,,不过那个复杂度貌似有点不合理。
虽然给定的数组不是按序给定的,但是,我们要知道,在这个算法的世界里面,有序的话,一切都很简单了。
有序的价值啊。可惜我的生活现在还是有些混乱无章。。。。
但是因为最后要返回的是原数组的元素下标,因此,我们必须要在使用原数组的空间做一个副本。对所得的副本采用以下算法。
- 算法
关键算法如下:
对所得副本选取最左和最右两个游标,取二者之和,若和等于目标值,将这个所代表的元素在原数组查找确定下标,然后保存在index中。留待返回。
若和大于目标值,则让右下标往左移;
若和小于目标值,则让左下标往右移。
直至左右相等之前为止。
二、问题的提出
经代码的实现检验,以上算法是切实可行的。但能否从数学的角度,对其可行性进行证明?于是我们提出了以下证明题:
对于一个有序整数数列,已知其中有且只有一对数字(两个数)的和为一个给定值,试证明可以通过以上算法找出这两个数。
三、问题的解决
假定这两个要找的数分别为p和q(且p<=q)。
由于算法中分别由最左(小)和最右(大)的两个数作为游标开始查找,我们试分以下两种情况讨论:
情况一:
若最左数和最右数的和正好等于给定值,则最左数和最右数即为要找的两个数;
情况二:
若最左数和最右数的和不等于给定值,则需逐步往右移动左游标,或往左移动右游标。由于题中已假定了该对整数的唯一性,我们只需要证明可以找到。但在左游标右移和右游标左移的情况下,是否可能出现左游标错过了p,右游标错过q的情形。其中一个可能错过的情形是:当左游标未到达p时,右游标已经移动到小于q的位置。
本篇博客想要证明的就是这种“错过”情形不会发生。
我们将整个数列分为三个区间:
区间一:[最左值,p),包含最左值,不包含p;
区间二:[p,q],包含p,也包含q;
区间三:(q,最右值],不包含q,包含最右值。
那么,在左游标右移和右游标左移的过程中,必然有其中之一先进入区间二,不妨设为左游标刚刚到达p处。此时右游标仍处于区间三。从而左游标+右游标的和必然超过给定值,根据算法,右游标会一直左移,直到到达q处。
这便证明了“错过”的情形不会发生。
版权声明:本文为博主原创文章,未经博主允许不得转载。