167. 两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组 numbers
,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1]
和 numbers[index2]
,则 1 <= index1 < index2 <= numbers.length
。
以长度为 2 的整数数组 [index1, index2
] 的形式返回这两个整数的下标 index1
和 index2
。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
c
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
c
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
c
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2]
c
提示:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
方法1------ 直接枚举
c
// C
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
*returnSize = 2; // 题目保证一定会给存在解
int *ret = (int * )malloc(sizeof(int) * 2);
for(int i = 0;i<numbersSize;i++){
for(int j = i+1;j<numbersSize;j++){
if(numbers[i]+ numbers[j] == target){
ret[0] = i + 1;
ret[1] = j + 1;
break;
}
}
}
return ret;
}
cpp
// C++
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ret{1001,1001};
for(int i = 0;i<numbers.size();i++){
for(int j = i+1;j<numbers.size();j++){
if(numbers[i]+ numbers[j] == target){
ret[0] = i + 1;
ret[1] = j + 1;
break;
}
}
}
return ret;
};
- 时间复杂度:O( n 2 n^2 n2)
- 空间复杂度:O(1)
方法2------ 相向双指针
注意到 数组是有序的。利用有序数组的性质(数组升序排列)。
- 初始化左右指针
l = 0;r =numberSize-1;
- 枚举当前最小值 m i n l min_l minl + 当前数组最大值 m a x r max_r maxr
- m i n l min_l minl + m a x r max_r maxr > target 说明最大值 m a x r max_r maxr 过大,增大最小值没有意义,需要最大值缩小,即右指针
r
向左移动。 - m i n l min_l minl + m a x r max_r maxr < target 说明最小值 m i n l min_l minl 过小,增大最小值没有意义,需要最大值缩小,即右指针
l
向右移动。
c
//C
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int *ret = (int *)malloc(sizeof(int)*2);
memset(ret,0,sizeof(int));
*returnSize = 2;
int l = 0,r = numbersSize - 1;
int mid,sum;
while(l<r){
sum = numbers[l] + numbers[r];
if(sum == target){
ret[0] = l+1;
ret[1] = r+1;
return ret;
}else if(sum > target){
r--;
}else{
l++;
}
}
return NULL;
}
cpp
//C++
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ret{1001,1001};
int l = 0;
int r = numbers.size() - 1;
while( l < r){
if (numbers[l] + numbers[r] > target) r--;
else if(numbers[l] + numbers[r] < target) l++;
else if(numbers[l] + numbers[r] == target) {
ret[0] = l+1;
ret[1] = r+1;
break;
}
}
return ret;
}
};
python
# python
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
l,r = 0,len(numbers)-1
while l < r:
sum = numbers[l] + numbers[r]
if sum > target: r-=1
elif sum < target: l+=1
else: return[l+1,r+1]
return None
java
// java
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0;
int r = numbers.length-1;
int[] ret = {1001,1001};
while(l < r){
if(numbers[l] + numbers[r] == target){
ret[0] = l + 1;
ret[1] = r + 1;
break;
}else if(numbers[l] + numbers[r] > target) r--;
else l++;
}
return ret;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)