输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]
示例 2:
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]
限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路1: 利用哈希表,这思路和LeetCode第一题类似,但这样显然是没用到排序好了的这个性质,所以为下策。
class Solution {
public:
unordered_map<int,int> table;
vector<int> res;
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
if(n == 0)
return res;
for(int i = 0;i < n; ++i)
{
table[nums[i]] = i;//存储下标
}
int index = 0;
for(int i = 0;i < n;++i)
{
int rest = target - nums[i];
if(table.find(rest) == table.end())//说明没找到与nums[i]相加为target的数
continue;
else
{
index = table[rest];
if(index == i) //排除和自己相加的和为target
continue;
else
{
res.push_back(nums[i]);
res.push_back(nums[index]);
break;
}
}
}
return res;
}
};
思路二:因为数组是已经排序好的,我们可以使用两个指针,分别从前和后向中间遍历,如果这两个指针所指向的数字的和小于target
,那么说明我们选取的数字有点偏小,那么我们将左边的指针往右移动,反之说明我们选择的数字过于大了,那么就将右边的指针往左边移动。
class Solution {
public:
vector<int> res;
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
if(n == 0)
return res;
int left = 0;
int right = n - 1;
while(left < right)
{
if(nums[left] + nums[right] > target)
{
right--;
}
else if(nums[left] + nums[right] < target)
{
left++;
}
else
{
res.push_back(nums[left]);
res.push_back(nums[right]);
break;
}
}
return res;
}
};