Two Sum II – Input array is sorted

来源:互联网 发布:svm算法步骤 编辑:程序博客网 时间:2024/05/18 02:49

Question:
Similar to Question [1. Two Sum], except that the input array is already sorted in ascending order.

Solution:
Of course we could still apply the [Hash table] approach, but it costs us O(n) extra space, plus it does not make use of the fact that the input is already sorted.

O(n log n) runtime, O(1) space – Binary search:
For each element x, we could look up if target – x exists in O(log n) time by applying binary search over the sorted array. Total runtime complexity is O(n log n).

/*************************************************************************    > File Name: Inputarrayissorted.cpp    > Author: Mandagod    > Blog: http://blog.csdn.net/mandagod    > Mail: manda2003@163.com    > Created Time: 2016年07月09日 星期六 00时23分48秒 ************************************************************************/#include<iostream>#include<vector>using namespace std;class Solution {public:    // 2    // When sorted arrry, in ascending order?    vector<int> twoSum2(vector<int>& nums, int target) {        vector<int> result;        // Assume input is already sorted.        for (int i = 0; i < nums.size(); i++) {            int j = bsearch(nums, target - nums[i], i + 1);            if (j != -1) {                result.push_back(i);                 result.push_back(j);                return result;            }        }        return result;      }    // 3    vector<int> twoSum3(vector<int>& nums, int target) {        vector<int> result;        // Assume input is already sorted.        int i = 0, j = nums.size() - 1;        while (i < j) {            int sum = nums[i] + nums[j];            if (sum < target) {                i++;            } else if (sum > target) {                j--;            } else {                result.push_back(i);                 result.push_back(j);                return result;            }        }        return result;    }private:    int bsearch(vector<int>& A, int key, int start) {        int L = start, R = A.size() - 1;        while (L < R) {            int M = (L + R) / 2;            if (A[M] < key) {                L = M + 1;            } else {                R = M;            }        }        return (L == R && A[L] == key) ? L : -1;    }};int main() {    /*    Given nums = [2, 7, 11, 15], target = 9,    Because nums[0] + nums[1] = 2 + 7 = 9,    return [0, 1].    */    // the iterator constructor can also be used to construct from arrays:    int myints[] = {2, 7, 11, 15};    vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );    cout << "The contents of fifth are:";    for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)        cout << ' ' << *it;    cout << '\n';    Solution sol;    int target = 9;    cout << "target: " << target << "\n";     vector<int> res2 = sol.twoSum2(fifth, target);    cout << "The result2 of test:";    for(vector<int>::iterator it = res2.begin(); it != res2.end(); ++it)        cout << ' ' << *it;    cout << "\n";    vector<int> res3 = sol.twoSum2(fifth, target);      cout << "The result3 of test:";    for(vector<int>::iterator it = res3.begin(); it != res3.end(); ++it)        cout << ' ' << *it;    cout << "\n";     return 0;}// run resultsThe contents of fifth are: 2 7 11 15target: 9The result2 of test: 0 1The result3 of test: 0 1

O(n) runtime, O(1) space – Two pointers:
Let’s assume we have two indices pointing to the ith and jth elements, Ai and Aj
respectively. The sum of Ai and Aj could only fall into one of these three possibilities:
i. Ai + Aj > target. Increasing i isn’t going to help us, as it makes the sum even
bigger. Therefore we should decrement j.
ii. Ai + Aj < target. Decreasing j isn’t going to help us, as it makes the sum even
smaller. Therefore we should increment i.
iii. Ai + Aj == target. We have found the answer.

    // 3    vector<int> twoSum3(vector<int>& nums, int target) {        vector<int> result;        // Assume input is already sorted.        int i = 0, j = nums.size() - 1;        while (i < j) {            int sum = nums[i] + nums[j];            if (sum < target) {                i++;            } else if (sum > target) {                j--;            } else {                result.push_back(i);                 result.push_back(j);                return result;            }        }        return result;    }
0 0