167.两数之和(双指针) 难度:简单
题目描述:
给定一个已按照升序排列的整数数组 numbers
,请你从数组中找出两个数满足相加之和等于目标数 target
。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers
的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length
。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
考察的是双指针,算法解释如下:
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。
若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口) ,经常用于区间搜索。
若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。
我的思路:
1.设置左指针 i
(向右滑动)和右指针 j
(向左滑动)
2.设置循环,循环条件为:i<j
3.三个选择分支:① numbers[i] + numbers[j] == target
时,满足条件,跳出循环;
② numbers[i] + numbers[j] < target
时,左指针向右滑动一格,即 i++
;
③ numbers[i] + numbers[j] > target
时,右指针向左滑动一格,即 j--
;
4.返回两个数的下标值,即 return new int[]{i+1,j+1}
;
技能补充:
返回数组的格式: return new int[]{i,j}
我的Java代码:
int[] numbers = new int[]{-1,0}; //输入数组
int target = -1; //目标值
int i=0; //左指针
int j=numbers.length-1; //右指针
// for(;;){ //这是我原先的解法
for(;i<j;){ // 加了判断条件后,return后面就不用调用Math.min()方法了
if(numbers[i] + numbers[j] == target){
//System.out.println("序号分别为:"+Math.min(i+1, j+1)+"和"+Math.max(i+1, j+1));
System.out.println("序号分别为:"+(i+1)+"和"+(j+1);
break;
}else if(numbers[i] + numbers[j] < target){
i++;
}else{
j--;
}
}
复杂度分析:
时间复杂度:O(n)
,其中 n
是数组的长度。两个指针移动的总次数最多为 n
次。
空间复杂度:O(1)
。