Task

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

1
2
3
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.

Solution

双指针

  • 指针l和r分别从左右两端开始向中间移动
    • 若两指针对应元素之和sum大于target,则需减小这个sum,右侧指针r向左移动
    • 若两指针对应元素之和sum小于target,则需增加这个sum,左侧指针l向左移动
    • 若两指针对应元素之和sum等于target,则直接返回
  • 时间复杂度:只遍历一次,O(n)
  • 空间复杂度:只分配了指针,O(1)
  • 实现:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Runtime: 8 ms, faster than 58.52% of C++ online submissions for Two Sum II - Input array is sorted.
// Memory Usage: 9.8 MB, less than 7.84% of C++ online submissions for Two Sum II - Input array is sorted.
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)
                --r;
            else
                ++l;
        }
        return {};
    }
};

二分查找

  • 使用一个指针i遍历数组,每次对其右侧部分做二分查找,找到能与i匹配的则返回
  • 时间复杂度:二分查找是O(log(n)),遍历时每次都二分查找,就是O(nlog(n))
  • 空间复杂度:只分配了指针,O(1)
  • 实现:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Runtime: 12 ms, faster than 31.77% of C++ online submissions for Two Sum II - Input array is sorted.
// Memory Usage: 9.7 MB, less than 11.76% of C++ online submissions for Two Sum II - Input array is sorted.
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        //取一个元素
        for(int i=0;i<numbers.size();++i){
            int l=i+1,r=numbers.size()-1;
            int delta=target-numbers[i];
            //对其右侧二分查找
            while(l<=r){
                int m=(l+r)/2;
                if(numbers[m]==delta)
                    return {i+1,m+1};
                else if(numbers[m]>delta)
                    r=m-1;
                else
                    l=m+1;
            }
        }
        return {};
    }
};