给你一个下标从 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
- 仅存在一个有效答案
步骤1:问题分析
这是一个经典的双指针问题。给定一个已按非递减顺序排列的数组 numbers
,从中找到两个数,使得它们的和等于指定的目标值 target
。该问题的输入输出和限制条件如下:
- 输入:
- 一个整数数组
numbers
,长度范围为[2, 3*10^4]
。 - 一个整数
target
,表示两个数的目标和。
- 一个整数数组
- 输出:
- 返回两个整数的下标
[index1, index2]
,满足numbers[index1] + numbers[index2] = target
且1 <= index1 < index2 <= numbers.length
。
- 返回两个整数的下标
- 限制条件:
- 只存在唯一解。
- 数组已按非递减顺序排列。
- 需要常量级的额外空间。
边界条件包括:
numbers
数组只有两个元素。- 数组中可能有负数。
步骤2:解题思路
由于数组已排序,且每个元素仅使用一次,因此最优解法是 双指针法,能够在 O(n) 时间复杂度内解决,并符合常量空间要求。
具体算法思路
-
初始化双指针:
- 定义
left
指针指向数组开头,right
指针指向数组末尾。
- 定义
-
双指针遍历:
- 计算
left
和right
指针所指元素的和。 - 若和等于目标值
target
,返回[left+1, right+1]
(题目要求索引从 1 开始)。 - 若和小于
target
,增加left
指针以增大和。 - 若和大于
target
,减小right
指针以减小和。
- 计算
-
终止条件:
- 当找到满足条件的两个数时退出循环,返回它们的索引。
算法复杂度分析
- 时间复杂度:O(n),因为只需遍历数组一次。
- 空间复杂度:O(1),只用到固定数量的指针和变量。
这种双指针方法能在常量空间内快速定位目标值,因此是最优解。
步骤3:C++代码实现
步骤4:启发与算法优化
- 启发:排序数组的特点可以简化许多查找问题。在本题中,我们利用了双指针技术,使得时间复杂度降到 O(n),并且仅用 O(1) 的空间。
- 优化思路:如果数组未排序,可先排序,再使用双指针方法,时间复杂度为 O(n log n),适用于较大的数据集。
- 效率提升:这种方法特别适用于数据规模大且已排序的查找类问题,避免了 O(n^2) 的复杂度。
步骤5:实际应用
应用场景:此算法在金融行业的配对交易策略中有广泛应用。例如,在证券市场中,配对交易策略要求找到成对的股票,使得在满足一定条件下购买一支股票并卖出另一支。
实际应用示例:
假设有一组股票的收益预期值已按从低到高排序,交易员希望找到两支股票组合,其收益和达到某个指定目标收益。利用该算法可以高效地确定满足条件的股票对,而无需穷举所有组合。在实现上,将收益预期作为 numbers
,目标收益作为 target
,借助双指针法即可找到合适的股票对,快速执行配对交易。