1. 程式人生 > >[LeetCode] Two Sum II

[LeetCode] Two Sum II

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 {};
    }
};

類似題目:

參考資料: