[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;
}
};
很遗憾,并不是所有暴力都能解决问题——超时了 🥀。
![](https://img2022.cnblogs.com/blog/2907270/202207/2907270-20220721170400136-263834219.jpg)
--- ### 💡使用双指针解决问题 #### 算法思路 * i指向数组头元素,j指向数组尾元素,只要i
代码
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};
}
};