LeetCode刷题:双指针 [167.两数之和 II - 输入有序数组] - Java版本

双指针:两数之和

只是记录自己的刷题过程,答案参考过多种题解。

如有错误感谢指正!

参考:LeetCode 101: A LeetCode Grinding Guide (C++ Version) 作者:高畅 Chang Gao

题目来源:题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 (leetcode-cn.com)

A. 双指针思想

  • 因为数组已经排好序,我们可以采用 方向相反的双指针 来寻找这两个数字。

B. 具体实现

  • 两个指针,一个初始指向最小的元素,即数组最左边,向右遍历;一个初始指向最大的元素,即数组最右边,向左遍历。

  • 如果两个指针指向元素的和 等于 给定值,那么它们就是我们要的结果;如果两个指针指向元素的和 小于 给定值,我们把左边的指针右移一位,使得当前的和增加一点;如果两个指针指向元素的和 大于 给定值,我们把右边的指针左移一位,使得当前的和减少一点。

C. 思考

  • 可以证明,对于 排好序且有解 的数组,双指针一定能遍历到最优解。

  • 证明方法如下:假设最优解的两个数的位置分别是 l 和 r。我们假设在左指针在 l 左边的时候,右指针已经移动到了 r;此时两个指针指向值的和小于给定值,因此左指针会一直右移直到到达 l。同理,如果我们假设 在右指针在 r 右边的时候,左指针已经移动到了 l;此时两个指针指向值的和大于给定值,因此右指针会一直左移直到到达 r。所以双指针在任何时候都不可能处于 (l,r) 之间,又因为不满足条件时指针必须移动一个,所以最终一定会收敛在 l 和 r。

  • 如果数组没有排序,且题目要求和数组顺序无关,可以考虑采取先排序后双指针的做法。

  • 缩减搜索空间 的角度思考。无论 A[i] + A[j] 的结果是大了还是小了,我们都可以排除掉一行或者一列的搜索空间。经过 n 步以后,就能排除所有的搜索空间,检查完所有的可能性。

D. 代码

public int[] twoSum(int[] numbers, int target) {
    int start = 0, end = numbers.length - 1, sum;
    while (start < end) {
    sum = numbers[start] + numbers[end];
    	if (sum == target) {
    		return new int[]{start + 1, end + 1}; //按要求返回新数组
        } else if (sum < target) { // 结果小于给定值,则开始的指针下标自增
            ++start;
        } else { // 结果大于给定值,则结束的指针下标自减
            --end;
        }
    }
    return new int[]{-1, -1};
}

猜你喜欢

转载自blog.csdn.net/weixin_51909882/article/details/123221618
今日推荐