👀 题目:
给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
✔ 样例:
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
👍解答:
解法一:双指针
根据题目我们可以知道,这个数组是不严格递增排列的数组,那么我们要找到两个数,使其之和等于目标值target的话,不妨从头和尾分别取一个数来相加。
- 如果相等,那么直接返回结果。
- 如果小于目标值,就让左指针加一(根据不严格递增数组的顺序来看,如果右指针减一的话,那么和就会更小了)
- 如果大于目标值,就让右指针减一
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> arr;
int left = 0,right = numbers.size()-1;
while(left < right){
int num_left = numbers[left];
int num_right = numbers[right];
if(num_left + num_right == target){
arr.push_back(left+1);
arr.push_back(right+1);
break;
}else if(num_left + num_right < target){
left++;
}else{
right--;
}
}
return arr;
}
};
解法二:二分查找
从头部依次开始取作为基准数,在剩下的序列中找到一个数,是其与当前基准数的和等于目标值target,那么就可以利用二分查找。另外,一旦发现一组元素满足条件,就不需要再继续判断下去了。
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> arr;
bool flag = false;
for(int i = 0;i < numbers.size();i++){
if(flag) break;
int temp = numbers[i];
int left = i + 1,right = numbers.size()-1;
while(left <= right){
int mid = (right - left) / 2 + left;
if(numbers[mid] + temp == target){
arr.push_back(i + 1);
arr.push_back(mid + 1);
flag = true;
break;
}else if(numbers[mid] + temp < target){
left = mid + 1;
}else{
right = mid - 1;
}
}
}
return arr;
}
};