Two Sum
Given an array of integers, 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.Given an array of integers, find two numbers such that they add up to a specific target number.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
Output: index1=1, index2=2
Thoughts:
If the array is not sorted, then the brutal way time complexity is O(n^2) = n(n-1).
When treating search problem, sorting is usually helpful. After sort, we can use two pointers pointing at the beginning and the end of the array. If the sum of numbers at two pointers larger than target, left-move the pointer at right; otherwise right-move the pointer at last until the solution is found, which the problem ensured.
The algorithm has time complexity O(nlogn) + O(n) = O(nlogn). The first term is for sorting, and the second term is for searching. Before we sort, we need to record the original indices for each elements, this will require an extra O(2n) space complexity.
Solution:
- class Solution {
- public:
- typedef pair<int, size_t> valoffset_pair_t;
- vector<int> twoSum(vector<int> &numbers, int target) {
- vector<valoffset_pair_t> new_array;
- // Preallocate the memory for faster push_back
- new_array.reserve(numbers.size());
- // generate the new array
- int index=0;
- for(auto i : numbers)
- new_array.push_back(valoffset_pair_t(i, ++index));
- // Note: here the index is already increased, so
- // the new indices are not zero based
- // sort it!
- sort(begin(new_array), end(new_array),
- [&](const valoffset_pair_t& v1, const valoffset_pair_t& v2) -> bool
- {
- return v1.first < v2.first;
- }
- );
- // now find the right pair using two pointers
- auto p_left=begin(new_array);
- auto p_right=end(new_array);
- p_right--; // make it locate at the last position
- int sum = p_left->first + p_right->first;
- // it is guaranteed to have one exact solution
- while(sum!=target)
- {
- sum = p_left->first + p_right->first;
- if (sum > target)
- p_right--;
- else if (sum < target)
- p_left++;
- else
- break;
- }
- return vector<int>(
- {min(p_left->second, p_right->second),
- max(p_left->second, p_right->second)});
- }
- };
No comments:
Post a Comment