难度:中等
目录
一、问题描述
这里直接采用LeetCode上面的问题描述。
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
下面给出示例:
提示:
- 2 <= numbers.length <= 3 * 104
- -1000 <= numbers[i] <= 1000
- numbers 按 非递减顺序 排列
- -1000 <= target <= 1000
- 仅存在一个有效答案
二、解题思路
1、思路
1.1 双指针
这里要查找的是两数之和问题,也可以参考1.两数之和,该题顺序都是有序的若是使用双指针都不需要进行排序了,直接开整。
1.2 二分查找
但是除了双指针,这里介绍另一种解法,循环开始使用二分查找进行查找 与 当前数 numbers[ i ] 相加起来等于 target 的数,每次从 [i+1, numbers.size()-1] 开始进行二分查找,找到返回其下标,否则返回 0 。即可,但是时间复杂度也是 ,没有双指针的时间复杂度低。
但是也可以是一种思路。
三、解题
1、代码实现
1.1 双指针
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int l = 0, r = numbers.size()-1;
while(l < r){
if(numbers[l] + numbers[r] < target){
l++;
}else if(numbers[l] + numbers[r] > target){
r--;
}else{
return {l+1,r+1};
}
}
return {0,0};
}
};
1.2 二分查找
class Solution {
public:
//二分查找,找到返回其下标
int BinarySerach(int l, int r,vector<int>& numbers, int target){
if(l > r){
return 0;
}
int mid = l + (r - l) / 2;
if(numbers[mid] == target){
return mid;
}
return numbers[mid] > target ? BinarySerach(l, mid - 1, numbers, target) : BinarySerach(mid + 1, r, numbers, target);
}
vector<int> twoSum(vector<int>& numbers, int target) {
int lenghtNumbers = numbers.size();
//进行遍历
for(int i = 0; i < lenghtNumbers-1; i++){
//这里 查找剩下的数中是否有满足 target - numsbers[i] 的数
int j = BinarySerach(i+1, lenghtNumbers-1, numbers, target - numbers[i]);
//如果返回的下标不为 0 即查找到了这个数 返回其位置
if(j){
return {i+1,j+1};
}
}
//一定存在一个解,所以这里不重要
return {0,0};
}
};
2、时间复杂度 and 空间复杂度
2.1 双指针
时间复杂度:
空间复杂度:
2.2 二分查找
时间复杂度:
空间复杂度: