[LeetCode] 两数之和 II - 输入有序数组

📃题目

给你一个下标从 1开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] numbers[index2] ,则1 <= index1 < index2 <= numbers.length

以长度为 2 的整数数组[index1, index2]的形式返回这两个整数的下标 index1 index2

你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

作者:力扣 (LeetCode)
链接:https://leetcode.cn/leetbook/read/all-about-array/x9i1x6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

示例1

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例2

输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

示例3

输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

提示

  • 2 <= numbers.length <= 3 * \(10^4\)
  • -1000 <= numbers[i] <= 1000
  • numbers 按 非递减顺序 排列
  • -1000 <= target <= 1000
  • 仅存在一个有效答案

🐷暴力思路

一开始我直接来一个for循环嵌套:

  • 两层循环,时间复杂度\(O(n^2)\)
  • 思路很简单,就是外层循环指向一个数,内层循环指向另一个数,一个一个加起来对比target,直到找出答案。

:C++代码

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int len = numbers.size();
        vector<int> ans;	//用于放置答案的vector
        bool flag = false;	//判断是否已找到答案
        for(int i=0;i<len-1;i++){	//i指向较小的数
            for(int j=i+1;j<len;j++){	//j指向较大的数
                if(numbers[i] + numbers[j] == target){	
		//如果找到答案了就退出循环,返回答案
                    flag = true;
                    ans.push_back(i+1);
                    ans.push_back(j+1);
                    break;
                }
            }
            if(flag)break;
        }
        return ans;
    }
};

很遗憾,并不是所有暴力都能解决问题——超时了 🥀。


--- ### 💡使用双指针解决问题 #### 算法思路 * i指向数组头元素,j指向数组尾元素,只要itarget`,说明当前两数之和较大,则执行`j--`。 #### 算法分析 **时间复杂度**:i和j从数组的头和尾向中间走,整个过程数组遍历一次,故时间复杂度为$O(n)$。 **空间复杂度**:此算法不需要额外的空间,空间复杂度为$O(1)$.

代码

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int i=0;			//i指向数组头部
        int j = numbers.size() -1;	//j指向数组尾部
        while(i<j){
            if(numbers[i]+numbers[j] == target)return {i+1,j+1};//找到答案
            if(numbers[i]+numbers[j] < target) i++;		//当前两数之和太小
            if(numbers[i]+numbers[j] > target) j--;		//当前两数之和太大
        }

	//{-1,-1}对应找不到答案的情况,不过这道题目的测试点似乎会保证有且仅有一个答案。
        return {-1,-1};
    }
};
posted @ 2022-07-21 17:45  feixianxing  阅读(29)  评论(0编辑  收藏  举报