个人主页:五敷有你
系列专栏:算法分析与设计
⛺️稳中求进,晒太阳
给你一个下标从 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-5,直到找到答案或者指针相遇。
双指针技巧在解决一些搜索、遍历、判断问题时具有很高的效率,能够将时间复杂度降低到线性级别。
定义两个指针
left
和right
,分别指向数组的起始位置和末尾位置。在每一步迭代中,计算指针所指元素的和
currentSum
。如果
currentSum
等于目标数target
,则找到了满足条件的两个数,返回它们的下标(注意下标是从1开始的)。如果
currentSum
小于目标数target
,则将left
指针向右移动一位,以增大和。如果
currentSum
大于目标数target
,则将right
指针向左移动一位,以减小和。重复步骤2-5,直到找到满足条件的两个数或者指针相遇。
由于数组已按非递减顺序排列,通过这种双指针的方式,可以高效地找到答案。这个算法的时间复杂度是 O(n),其中 n 是数组的长度。
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int left = 0;
int right = numbers.length - 1;
while (left < right) {
int currentSum = numbers[left] + numbers[right];
if (currentSum == target) {
return new int[]{left + 1, right + 1}; // 返回下标(注意下标是从1开始的)
} else if (currentSum < target) {
left++;
} else {
right--;
}
}
// 如果没有找到满足条件的两个数,返回空数组或者其他指定的值
return new int[]{};
}
}
这个算法的时间复杂度是 O(n),其中 n 是数组的长度。