leetcode
leetcode 151 ~ 200
两数之和 II - 输入有序数组

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

难度:

标签:

题目描述

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1]numbers[index2] ,则 1 <= index1 < index2 <= numbers.length

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 index2

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

 

示例 1:

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例 2:

输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

示例 3:

输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

 

提示:

  • 2 <= numbers.length <= 3 * 104
  • -1000 <= numbers[i] <= 1000
  • numbers非递减顺序 排列
  • -1000 <= target <= 1000
  • 仅存在一个有效答案

代码结果

运行时间: 40 ms, 内存: 15.3 MB


/*
 * 思路:
 * 使用Java Stream API的方法来解决这个问题。我们可以将numbers数组与其索引一起流式处理,
 * 以查找符合条件的两个数。
 */
import java.util.stream.IntStream;
 
public int[] twoSum(int[] numbers, int target) {
    return IntStream.range(0, numbers.length)
        .boxed()
        .flatMap(i -> IntStream.range(i + 1, numbers.length)
            .filter(j -> numbers[i] + numbers[j] == target)
            .mapToObj(j -> new int[] {i + 1, j + 1}))
        .findFirst()
        .orElse(new int[] {-1, -1}); // 保证有唯一解
}

解释

方法:

这个题解使用双指针的方法在有序数组中查找两数之和等于目标值的一对数字。初始时左指针 lo 指向数组开头,右指针 hi 指向数组结尾。每次计算两个指针对应元素之和 s,如果 s 小于目标值,说明需要增大 lo 以获得更大的值;如果 s 大于目标值,说明需要减小 hi 以获得更小的值;如果 s 等于目标值,则找到了符合条件的一对数,返回它们的下标即可。在移动指针时,还跳过了重复的元素以优化效率。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
如何确保在跳过重复元素时,指针不会越过数组的边界,从而导致程序出错?
在代码中,跳过重复元素的循环条件包括了 'lo < hi',这确保了在指针移动的过程中不会越过对方的指针,从而避免了数组越界的问题。无论是左指针向右移动,还是右指针向左移动,循环都会在两指针相遇或交叉前停止,确保每次操作都在安全的数组索引范围内。
🦆
在题解中提到的跳过重复元素的步骤是否可能导致错过某些潜在的正确答案,特别是在数组中存在多个重复元素时?
不会错过正确答案。因为数组是有序的,当遇到一个元素与之前元素重复时,如果这个重复元素的组合未能与目标值匹配,则其他同样的重复元素也不会匹配目标值。跳过重复元素的策略仅在已确定当前组合不满足条件时使用,因此不会影响查找结果的正确性。
🦆
为什么在找到和等于目标值时,直接返回下标而不再检查其他可能的组合?
由于题目的要求是找到一对数的索引,其中这对数的和正好等于目标值,并且数组是有序的,所以当找到这样一对数时,这是唯一可能的解决方案。数组的有序性保证了一旦找到符合条件的一对数,就没有必要继续搜索,因为不可能存在其他的组合能够得到相同的目标值。
🦆
在实现双指针算法时,如果数组中所有元素相加的总和都不等于目标值,算法是如何终止的?
如果数组中不存在两个元素的和等于目标值,双指针算法会在左指针超过右指针的情况下终止。这通常发生在两个指针相遇之后,其中一个指针继续移动以试图找到合适的配对。由于循环的条件是 'lo < hi',一旦这两个指针相交,循环就会停止,从而结束算法的执行,确保算法不会无限运行。

相关问题

两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

 

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

 

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

 

进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

两数之和 IV - 输入二叉搜索树

给定一个二叉搜索树 root 和一个目标结果 k,如果二叉搜索树中存在两个元素且它们的和等于给定的目标结果,则返回 true

 

示例 1:

输入: root = [5,3,6,2,4,null,7], k = 9
输出: true

示例 2:

输入: root = [5,3,6,2,4,null,7], k = 28
输出: false

 

提示:

  • 二叉树的节点个数的范围是  [1, 104].
  • -104 <= Node.val <= 104
  • 题目数据保证,输入的 root 是一棵 有效 的二叉搜索树
  • -105 <= k <= 105

小于 K 的两数之和

小于 K 的两数之和