题目:
今天这题之所以来写博客是因为解法确实有点巧妙。(我完全没想到来着)
我一开始想的是暴力搜索,但是毫无疑问会超时。于是用了一个二分查找法来优化它。但是效率也不是很理想:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> sup;
for(int i=0;i<nums.size();i++){
int ans = brisearch(nums,i,nums.size()-1,target - nums[i]);
if(ans!=-1){
sup.push_back(nums[i]);
sup.push_back(nums[ans]);
return sup;
}
}
return sup;
}
int brisearch(vector<int>& nums,int left,int right,int target){
while(left<=right){
int mid = left + (right-left)/2;
if(nums[mid]==target){
return mid;
}
else if(nums[mid]<target){
left = mid + 1;
}
else if(nums[mid]>target){
right = mid - 1;
}
}
return -1;
}
};
看了看题解,确实太妙了。
本质上的思想是使用一个双指针:
这样子遍历是可以保证不漏掉任何一个的。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
size_t l = 0;
size_t r = nums.size() - 1;
while (l < r) {
int sum = nums[l] + nums[r];
// 如果大于目标和,则右边的数要小一点
if (sum > target) {
r--;
}
// 如果小于目标和,则左边的数要大一点
else if (sum < target) {
l++;
}
// 如果等于目标和,则直接返回目标序列
else if (sum == target){
return vector<int>{nums[l], nums[r]};
}
}
return vector<int>{};
}
};