原題目:
Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
筆者嘗試了三種算法:
第一種簡單粗暴,直接兩重循環暴力搜索,複雜度爲O(n^2),不過很不幸,結果超出時間限制;
算法二是通過一重循環窮舉第一項,同時對第二項進行二分查找(給定數組已排好序),複雜度爲O(nlogn),雖然通過,但是效率還不是很高;
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ans;
int i, j = -1;
for(i=0; i<numbers.size(); i++)
{
int l = 0, h = numbers.size()-1;
while(l <= h)
{
if(numbers[(l+h)/2] == (target-numbers[i]))
{
j = (l + h) / 2;
if(j == i) j ++;
break;
}
else if(numbers[(l+h)/2] < (target-numbers[i]))
l = (l + h) / 2 + 1;
else h = (l + h) / 2 - 1;
}
if(j != -1) break;
}
ans.push_back(i+1);
ans.push_back(j+1);
return ans;
}
};
算法三:短小精悍,且高效,複雜度爲O(n)。設定兩個變量i和j分別指向數組開頭或者結尾,然後對向收縮,若numbers[i] + numbers[j]等於target,結束;若numbers[i]+numbers[j]<target,則i++;否則j++。詳見代碼:
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ans;
int i = 0, j = numbers.size()-1;
while(i < j)
{
if(numbers[i] + numbers[j] == target) break;
else if(numbers[i] + numbers[j] < target) i ++;
else j --;
}
ans.push_back(i+1);
ans.push_back(j+1);
return ans;
}
};