解题思路
自己开始的思路是,对另一个数,在已有的数组中进行二分查找,而不是简单的遍历,自己觉得复杂度挺小的O(nlogn),但是一直超时,同时自己的代码考虑了一种情况[2,7,7,10,11],target=9,如果是官方题解应该是返回值时{1,3};而我觉得正确的情况是[1,2](我写的代码可以获得该结果),因此从官方题解可以看出没有这种情况出现。代码见后
之后参考自LeetCode官方提解
使用两个指针,初始分别位于第一个元素和最后一个元素位置,比较这两个元素之和与目标值的大小。
如果和等于目标值,我们发现了这个唯一解。
如果比目标值小,我们将较小元素指针增加一。
如果比目标值大,将较大指针减小一。移动指针后重复上述比较直到找到答案。
时间复杂度O(n),空间复杂度O(1)
代码
双指针法
//双指针
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int low = 0, high = numbers.size() - 1;//low低指针,high高指针
while (low < high)
{
int sum = numbers[low] + numbers[high];
if (sum == target) return { low + 1,high + 1 };//学到了
else if (sum < target)
{
low++;
}
else if (sum > target)
{
high--;
}
}
return { -1,-1 };//学到了
}
};
自己的想法
//下列算法,超时无法通过题目
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> res;
for (int i=0;i<numbers.size();i++)
{
res.push_back(i+1);
int index = binarySearch(i+1, numbers, target - numbers[i]);
if (index != -1)
{
res.push_back(index+1);
return res;
}
res.pop_back();
}
return res;
}
//寻找左侧边界的二分搜索
int binarySearch(int i,vector<int> numbers,int target)
{
int left = i;
int right = numbers.size();
while (left<right) {
int mid = left + (right - left) / 2;
if (numbers[mid] == target) right=mid;
else if (numbers[mid] < target) {
left = mid + 1;
}
else if (numbers[mid]>target)
{
right = mid;
}
}
if (left == numbers.size()) return -1;
return numbers[left]==target?left:-1;
}
};