目录
引言
问题背景
输入输出规范
输入
输出
示例解析
示例 1
示例 2
示例 3
算法策略
Java代码实现
复杂度分析
结语
引言
在算法的世界里,有些问题虽然简单,但却是锻炼算法思维的绝佳练习。今天,我们将深入探讨一个在面试中经常出现的问题——两数之和。这个问题不仅考验我们对数组操作的熟练程度,还考察我们如何利用数组的特性来优化算法。本文将详细介绍如何使用双指针法解决两数之和问题,并提供Java语言的实现。
问题背景
给定一个整数数组 numbers
,该数组已经按照非递减顺序排列,以及一个目标整数 target
。我们的任务是从数组中找出两个数,使得它们的和等于 target
,并返回这两个数的下标(下标从 1 开始)。
输入输出规范
输入
- 整数数组
numbers
:一个已经排序的整数数组。 - 整数
target
:目标和。
输出
- 整数数组
[index1, index2]
:一个长度为 2 的数组,表示满足条件的两个数的下标。
示例解析
示例 1
输入:numbers = [2,7,11,15]
, target = 9
输出:[1,2]
解释:2 + 7 = 9
,因此返回下标 1
和 2
。
示例 2
输入:numbers = [2,3,4]
, target = 6
输出:[1,3]
解释:2 + 4 = 6
,因此返回下标 1
和 3
。
示例 3
输入:numbers = [-1,0]
, target = -1
输出:[1,2]
解释:-1 + 0 = -1
,因此返回下标 1
和 2
。
算法策略
双指针法是解决此类问题的常用策略。我们利用数组的有序性,通过两个指针 left
和 right
分别指向数组的两端,通过调整这两个指针的位置来寻找满足条件的两个数。
- 初始化:
left
指向数组的开始,right
指向数组的末尾。 - 计算和:计算
numbers[left]
和numbers[right]
的和。 - 调整指针:
- 如果和大于
target
,则right
向左移动,因为我们需要一个更小的数来减小总和。 - 如果和小于
target
,则left
向右移动,因为我们需要一个更大的数来增加总和。 - 如果和等于
target
,则找到了满足条件的两个数,返回它们的下标。
- 如果和大于
- 循环直至相遇:重复上述步骤,直到
left
和right
相遇。
Java代码实现
java
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] indices = {-1, -1}; // 用于存储结果的数组,初始化为-1表示未找到
int left = 0, right = numbers.length - 1; // 初始化左右指针
while (left < right) { // 循环直至左右指针相遇
int sum = numbers[left] + numbers[right];
if (sum == target) {
indices[0] = left + 1; // 记录下标
indices[1] = right + 1;
break; // 找到结果后跳出循环
} else if (sum < target) {
left++; // 增加总和
} else {
right--; // 减小总和
}
}
return indices; // 返回结果
}
}
复杂度分析
- 时间复杂度:O(n),其中 n 是数组
numbers
的长度。每个元素最多被访问两次。 - 空间复杂度:O(1),只需要常量级的额外空间来存储结果。
结语
通过双指针法,我们不仅解决了两数之和问题,还展示了如何利用数组的有序性来优化算法。这种方法的时间复杂度和空间复杂度都非常低,适用于处理大规模数据集。希望这篇文章能够帮助你深入理解双指针法,并将其应用到实际问题中。如果你有任何疑问或想要进一步探讨,欢迎在评论区交流。同时,如果你觉得这篇文章对你有帮助,不妨点个赞或者分享给需要的朋友。让我们一起进步,一起成长!
编辑注:本文旨在提供一个清晰、简洁且易于理解的解决方案,帮助读者掌握双指针法在解决实际问题中的应用。如果你有任何建议或反馈,欢迎在评论区提出,我们将不断优化内容,以提供更高质量的技术文章。