关于Two pointers的我的理解

刚刚在刷题的时候接触到了一道题,题的大意是给出一个递增的数字序列,并给出一个m,要求找到a,b两个数字,且和为m,而且a<b;
在示例中,给出了三种思路,二分、hash值、以及two pointers;
最后一种并无接触过,因此去了解了一下,发现是很值得借鉴的思路;数组

two pointers思想是对有序数组的优化遍历;
若是根据题目中的思想,进行两层枚举,则不可避免地会使时间复杂度到达O(n^2)级别。可是能够针对序列递增这一条进行优化;
对这个有序序列,设定两个索引坐标,一个为i,一个为j分别从队头和队尾进行向中间枚举,枚举的边界条件是i<j;
在枚举过程当中,一定会出现三种状况:
在此时注意一个前提条件:i必须保持增长状态,j必须保持减少状态;
1.a+b=m,此时是咱们想获得的状况,而且该状况发生时,若是i增大,j减少,则a+b可能和不变;
2.a+b>m,此时,在前提条件规范下,咱们能够推断若是b减少,也就是j减少,能够预测会出现a+b=m的状况;
3.a+b<m,此时,在前提条件规范下,咱们能够推断,若是a增大,也就是i增大,可能会出出现a+b=m的状况;
所以,将上述判别写成代码能够有如下结果:优化

while(i<j){
        if(a[i]+a[j]==m){
            i++;
            j--;
        }else if(a[i]+a[j]<m){
            i++;
        }else{
            j--;
        }
    }

这种方法能够当作是一种取巧的方法,可是其最大的特色是有效的减小了时间复杂度,在递增序列的前提下,循环只须要进行到i>=j时中止,因此理想状态下只须要遍历半个序列,时间复杂度只须要O(n),因此算得上求解的一种好方法;code

相关文章
相关标签/搜索