题目描述
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.
Note:
Your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
暴力解法。未利用数组有序的特性。
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// Brute Force
// Time Complexity: O(n^2)
// Space Complexity: O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
assert(numbers.size() >= 2);
// assert(isSorted(numbers));
for(int i = 0 ; i < numbers.size() ; i ++)
for(int j = i+1 ; j < numbers.size() ; j ++)
if(numbers[i] + numbers[j] == target){
int res[2] = {i+1, j+1};
return vector<int>(res, res+2);
}
throw invalid_argument("the input has no solution");//抛出异常
}
private:
bool isSorted(const vector<int>& numbers){
for(int i = 1 ; i < numbers.size() ; i ++)
if(numbers[i] < numbers[i-1])
return false;
return true;
}
};
void printVec(const vector<int>& vec){
for(int e: vec)
cout << e << " ";
cout << endl;
}
int main() {
int nums[] = {2, 7, 11, 15};
vector<int> vec(nums, nums + sizeof(nums) / sizeof(int));
int target = 9;
printVec(Solution().twoSum(vec, target));
return 0;
}
思路二
利用数组有序的特性,遍历过程中,对数组剩余部分进行二分查找。
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// Binary Search
// Time Complexity: O(nlogn)
// Space Complexity: O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
assert(numbers.size() >= 2);
// assert(isSorted(numbers));
for(int i = 0 ; i < numbers.size() - 1 ; i ++){
int j = binarySearch(numbers, i+1, numbers.size()-1, target - numbers[i]);
if(j != -1){
int res[2] = {i+1, j+1};
return vector<int>(res, res+2);
}
}
throw invalid_argument("the input has no solution");
}
private:
int binarySearch(const vector<int> &nums, int l, int r, int target){
assert(l >= 0 && l < nums.size());
assert(r >= 0 && r < nums.size());
while(l <= r){
int mid = l + (r - l)/2;
if(nums[mid] == target)
return mid;
if(target > nums[mid])
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
bool isSorted(const vector<int>& numbers){
for(int i = 1 ; i < numbers.size() ; i ++)
if(numbers[i] < numbers[i-1])
return false;
return true;
}
};
void printVec(const vector<int>& vec){
for(int e: vec)
cout << e << " ";
cout << endl;
}
int main() {
int nums[] = {2, 7, 11, 15};
vector<int> vec(nums, nums + sizeof(nums) / sizeof(int));
int target = 9;
printVec(Solution().twoSum(vec, target));
return 0;
}
思路三
对撞指针
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// Two Pointers
// Time Complexity: O(n)
// Space Complexity: O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
assert(numbers.size() >= 2);
// assert(isSorted(numbers));
int l = 0, r = numbers.size() - 1;
while(l < r){
if(numbers[l] + numbers[r] == target){
int res[2] = {l+1, r+1};
return vector<int>(res, res+2);
}
else if(numbers[l] + numbers[r] < target)
l ++;
else // numbers[l] + numbers[r] > target
r --;
}
throw invalid_argument("the input has no solution");
}
private:
bool isSorted(const vector<int>& numbers){
for(int i = 1 ; i < numbers.size() ; i ++)
if(numbers[i] < numbers[i-1])
return false;
return true;
}
};
void printVec(const vector<int>& vec){
for(int e: vec)
cout << e << " ";
cout << endl;
}
int main() {
int nums[] = {2, 7, 11, 15};
vector<int> vec(nums, nums + sizeof(nums) / sizeof(int));
int target = 9;
printVec(Solution().twoSum(vec, target));
return 0;
}