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
这又是一道Two Sum的衍生题,作为LeetCode开山之题,我们务必要把Two Sum及其所有的衍生题都拿下,这道题其实应该更容易一些,因为给定的数组是有序的,而且题目中限定了一定会有解,我最开始想到的方法是二分法来搜索,因为一定有解,而且数组是有序的,那么第一个数字肯定要小于目标值target,那么我们每次用二分法来搜索target - numbers[i]即可,代码如下:
解法一:
// O(nlgn) class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { for (int i = 0; i < numbers.size(); ++i) { int t = target - numbers[i], left = i + 1, right = numbers.size(); while (left < right) { int mid = left + (right - left) / 2; if (numbers[mid] == t) return {i + 1, mid + 1}; else if (numbers[mid] < t) left = mid + 1; else right = mid; } } return {}; } };
但是上面那种方法并不efficient,时间复杂度是O(nlgn),我们再来看一种O(n)的解法,我们只需要两个指针,一个指向开头,一个指向末尾,然后向中间遍历,如果指向的两个数相加正好等于target的话,直接返回两个指针的位置即可,若小于target,左指针右移一位,若大于target,右指针左移一位,以此类推直至两个指针相遇停止,参见代码如下:
解法二:
// O(n) class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int l = 0, r = numbers.size() - 1; while (l < r) { int sum = numbers[l] + numbers[r]; if (sum == target) return {l + 1, r + 1}; else if (sum < target) ++l; else --r; } return {}; } };
类似题目:
Two Sum III - Data structure design
参考资料:
https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/