167. 两数之和 II - 输入有序数组
- 第一种方法是利用map存入每个数,然后遍历原数组,判断target-numbers[i]存不存在map数组里,若存在返回两个数的下标即可,利用lower_bound会出错,因为当你本身是2的时候,目标是4,那么返回的是同一个位置的值,所以应当用upper_bound,因为肯定存在结果,所以返回这个下标就行。
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
map<int,int>mp;
for(int i=0;i<numbers.size();i++)
mp[numbers[i]]++;
for(int i=0;i<numbers.size();i++)
{
if(mp.count(target-numbers[i]))
{
int j=upper_bound(numbers.begin(),numbers.end(),target-numbers[i])-numbers.begin();
return {i+1,j};
}
}
return {1,1};
}
};
- 第二种方法是定义两个指针。头指针指向0,尾指针指向末尾,用sum计算这两个位置的数的和,如果等于target,那么返回这两个位置就行,如果大于的话,尾指针左移,缩小和,j--,否则左指针右移,增大和,i++,直到sum==target为止。
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int i=0,j=numbers.size();
int sum=0;
while(i<j)
{
sum=numbers[i]+numbers[j-1];
if(sum==target)
return {i+1,j};
else if(sum>target)
j--;
else
i++;
}
return {1,1};
}
};
- 二分查找 我们枚举左端点,二分中点,得到当起点为k时最优的中点,然后求numbers[k]+numbers[L],L为二分后最终的钟点。
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int L=0,R=0,ff=0;
for(int k=0;k<numbers.size()-1;k++){
int i=k+1,j=numbers.size()-1;
while(i<j)
{
int mid=(i+j)/2;
if(numbers[k]+numbers[mid]<target)
i=mid+1;
else
j=mid;
}
if(numbers[k]+numbers[i]==target)
{
L=k+1,R=i+1;
ff=1;
break;
}
}
return {L,R};
}
};