两种方式看搭配

117 阅读1分钟

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」。

前言

给定一个已按照 非递减顺序排列  的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
​
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
​
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素

image-20211125090201649.png

解题思路

  • 二分法应该是常见的思路。非递减排列就是增量排序。首先是边界和判定,如果不相同则左侧和二中侧数据和大于我们约定值,则右侧挪向中间,否则左侧移动。
class Solution {
    public int[] twoSum(int[] numbers, int target) {
        for (int i = 0; i < numbers.length; ++i) {
            int left = i + 1, right = numbers.length - 1;
            while (left <= right) {
                int mid = (right - left) / 2 + left;
                if (numbers[mid] == target - numbers[i]) {
                    return new int[]{i + 1, mid + 1};
                } else if (numbers[mid] > target - numbers[i]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
        }
        return new int[]{-1, -1};
    }
}

小结

  • 我们应该注意的是此题很局限,首先是有序递增的。并且最终有且仅会有一组数据成功。所以我们的二分法才会有效。之前我们刷leetcode应该都注意到往往二分法和双指针是并存的。二分法可以解决的事情双指针也是可以的。
  • 令左指针l = 0,右指针r = numbers.size() - 1,当l < r 进行循环
  • 当numbers[l] + numbers[r] == target时满足条件,退出循环
  • 若numbers[l] + numbers[r] > target 说明两数和太大,将右指针左移
  • 若numbers[l] + numbers[r] < target 说明两数和太小,将左指针右移
int l = 0,r = numbers.size() - 1,sum;
        while(l < r){
            sum = numbers[l] + numbers[r];
            if(sum == target) break;
            if(sum < target) l++;
            else r--;
        }
        return {l+1,r+1};

总结

  • 两数之和可以看成是两数搭配,暴力破解也会成功。人生也是如此一直等待值得你等待的人。