一、题目
给你一个下标从 1 开始的整数数组
numbers
,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数target
的两个数。如果设这两个数分别是numbers[index1]
和numbers[index2]
,则1 <= index1 < index2 <= numbers.length
。以长度为 2 的整数数组
[index1, index2]
的形式返回这两个整数的下标index1
和index2
。你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
二、思路
- 解法一击败 5.02% 用户,为什么总是想出这么离谱的题解...
- 姑且说说思路,要求两数相加为 target ,想到一个思路,1+4=5 等同于 5-1=4 ,用 target - number[slow] 得到的值与剩下的其他值做比较,若相等则说明找到了,此时记录下的 slow 与 fast 恰好为解;
- 解法一是一拍脑袋想出来的解法,这题既然是非递减排序,且是双指针的题,那有什么道理不用双指针?
- 既然排好序了,那就维护两个指针分别指向两端,left+right 要是大于 target 就 right-- ,小于就 left++ ,刚好等于就返回完事,见解法二;
三、解法
解法一
class Solution {
public int[] twoSum(int[] numbers, int target) {
int len = numbers.length;
int substract;
int[] ret = new int[2];
for (int slow = 0; slow < len - 1; slow++) {
substract = target - numbers[slow];
for (int fast = slow + 1; fast < len; fast++) {
if (substract == numbers[fast]) {
ret[0] = slow + 1;
ret[1] = fast + 1;
return ret;
}
}
}
throw new RuntimeException("题目骗人");
}
}
解法二
class Solution {
public int[] twoSum(int[] numbers, int target) {
int len = numbers.length;
int[] ret = new int[2];
int left = 0, right = len - 1;
while(left < right) {
int sum = numbers[left] + numbers[right];
if (sum == target) {
ret[0] = left + 1;
ret[1] = right + 1;
return ret;
} else if (sum > target) {
right--;
} else {
left++;
}
}
throw new RuntimeException("题目骗人");
}
}