Bootstrap

167.两数之和II-输入有序数组(力扣)-JAVA-两种双指针方法

167.两数之和II-输入有序数组

题目描述

在这里插入图片描述

1.双指针法

我们可以观察原数组得到(这里建议大家画图看看,真的非常清晰),因为题目一定有解,解唯一且数组按升序排列,所以我们不妨让left指针指向数组中未访问过的最小值(即从numbers[0]开始向右移动);让right指针指向数组中未访问过的最大值(即从numbers[n-1]开始向左移动)
若此时numbers[left]+numbers[right]>target,则将right指针向左移动right--(即用第二大的数与最小数相加试试),同理若numbers[left]+numbers[right]<target,则将left指针向右移动left++(即用稍微大一点的数相加试试);以此类推直到numbers[left]+numbers[right]==target
注意:题目要求结果下标从1开始计数,所以应将最终 right 和 left 加1存入新数组得到最终结果。

public int[] twoSum(int[] numbers, int target) {
        int left=0;
        int n=numbers.length;
        int right=n-1;
        while(left<right){
            if((numbers[left]+numbers[right])>target){
                right--;
            }else if(numbers[left]+numbers[right]<target){
                left++;
            }else{
                break;
            }
        }
        
        int[] newArr=new int[]{left+1,right+1};
        return newArr;
    }

2.二分查找法

利用数组的有序性质,可以使用二分查找的方法。即确定一个数(先从numbers[0]作为第一个确定的数,若i=0的一次for循环执行结束没有得到结果,执行i++,将numbers[1]作为第一个确定的数继续循环直到得到正确结果),然后通过二分查找int mid = (high - low) / 2 + low,判断numbers[mid] == target - numbers[i]是否成立;若numbers[mid] > target - numbers[i]则右指针向 high =mid-1,若numbers[mid] < target - numbers[i]则左指针low = mid+1;直至 low>right 结束此次对于第二个数的查找,若没有得到结果则说明第一个数不对,改变第一个数值继续执行二分查找第二个数;循环至获得最终结果。

public int[] twoSum(int[] numbers, int target) {
        for (int i = 0; i < numbers.length; i++) {
            int low = i + 1, high = numbers.length - 1;
            while (low <= high) {
                int mid = (high - low) / 2 + low; //防止超过int范围
                if (numbers[mid] == target - numbers[i]) {
                    return new int[]{i + 1, mid + 1};
                } else if (numbers[mid] > target - numbers[i]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
    }
;