👀 题目:

给定一个已按照 非递减顺序排列 的整数数组 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的话,不妨从头和尾分别取一个数来相加。

  1. 如果相等,那么直接返回结果。
  2. 如果小于目标值,就让左指针加一(根据不严格递增数组的顺序来看,如果右指针减一的话,那么和就会更小了)
  3. 如果大于目标值,就让右指针减一
    1. class Solution {
    2. public:
    3. vector<int> twoSum(vector<int>& numbers, int target) {
    4. vector<int> arr;
    5. int left = 0,right = numbers.size()-1;
    6. while(left < right){
    7. int num_left = numbers[left];
    8. int num_right = numbers[right];
    9. if(num_left + num_right == target){
    10. arr.push_back(left+1);
    11. arr.push_back(right+1);
    12. break;
    13. }else if(num_left + num_right < target){
    14. left++;
    15. }else{
    16. right--;
    17. }
    18. }
    19. return arr;
    20. }
    21. };

解法二:二分查找
从头部依次开始取作为基准数,在剩下的序列中找到一个数,是其与当前基准数的和等于目标值target,那么就可以利用二分查找。另外,一旦发现一组元素满足条件,就不需要再继续判断下去了。

  1. class Solution {
  2. public:
  3. vector<int> twoSum(vector<int>& numbers, int target) {
  4. vector<int> arr;
  5. bool flag = false;
  6. for(int i = 0;i < numbers.size();i++){
  7. if(flag) break;
  8. int temp = numbers[i];
  9. int left = i + 1,right = numbers.size()-1;
  10. while(left <= right){
  11. int mid = (right - left) / 2 + left;
  12. if(numbers[mid] + temp == target){
  13. arr.push_back(i + 1);
  14. arr.push_back(mid + 1);
  15. flag = true;
  16. break;
  17. }else if(numbers[mid] + temp < target){
  18. left = mid + 1;
  19. }else{
  20. right = mid - 1;
  21. }
  22. }
  23. }
  24. return arr;
  25. }
  26. };