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

153 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情

前言

力扣第167题 两数之和 II - 输入有序数组 如下所示:

image.png

一、思路

一、思路

题目很简单就是找出数组中的两个元素 nums[a]nums[b],使其满足 nums[a] + nums[b] == target

我看到既然是找到目标值,我的第一反应使用 哈希表 存储所有遍历过的元素,key 为元素的值,value 为元素的下标。这样就可以通过判断剩余值是否存在,来找到正确的两个元素。

nums = {2,3,4}, target = 6 作为例子,遍历第一个元素时,哈希表存储的实际内容为 {2, 4}

哈希表 思路的实现代码如下所示:

image.png

上面这种哈希表的方式,虽然能够通过用例,但是击败率只有 10%。转念一想,题目中给的 **非降序排列数组** 都没有用到,那要如何使用此关系呢?我们可以使用 双指针 来解决此题!

双指针

初始化变量
left:指向下标 0
right:指向 nums.len -1

我们知道 left ~ right 区间内,元素的值都是非递减的。我们可以判断左右边界和来缩小窗口,有如下的三种情况:

  1. nums[left] + nums[right] > traget:两者和大于目标值,说明应缩小右边界让和变小一点,即 right--
  2. nums[left] + nums[right] > traget:两者和小于目标值,说明应缩小左边界让和变大一点,即 left++
  3. nums[left] + nums[right] == traget:两者和等于目标值,返回左右边界即可

二、实现

实现代码

实现代码与思路中保持一致,此处只展示了 双指针 的实现方式

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

测试代码

public static void main(String[] args) {
    int[] nums = {2,3,4};
    new Number167().twoSum(nums, 6);
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~