[leetcode] 1.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.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

Solution 1. Sort + search           --> O(nlogn)                     

先排序,然后两个指针,一个在左left,一个在右right,

sorted[left] + sorted[right]

        = target ==> output

        > target ==> right--

        < target ==> left++

 1 #include <vector>

 2 #include <iostream>

 3 #include <algorithm>

 4 using namespace std;

 5 

 6 class Solution {

 7 private:

 8     typedef struct{

 9         int ind;

10         int val;

11     }ind_val_t;

12 

13 private:

14     static bool isSmaller(const ind_val_t a, const ind_val_t b)

15     {

16         return a.val < b.val;

17     }

18 

19 public:

20     vector<int> twoSum(vector<int> &numbers, int target)

21     {

22         int len = numbers.size();

23 

24         vector<ind_val_t> iv_vec(len);

25         for(int i=0; i<len; i++)

26         {

27             iv_vec[i].ind = i;

28             iv_vec[i].val = numbers[i];

29         }

30 

31         sort(iv_vec.begin(), iv_vec.end(), isSmaller);

32 

33         /* xi: the last element that < target/2 */

34         /* xj: xi + 1, the first elemet that >= target/2 */

35         int left=0, right=len-1;

36         vector<int> out(2);

37         while(left < right)

38         {

39             int sum = iv_vec[left].val + iv_vec[right].val;

40             if(sum == target)

41             {

42                 out[0] = iv_vec[left].ind + 1;

43                 out[1] = iv_vec[right].ind + 1;

44                 if(out[0] > out[1])

45                 {

46                     swap(out[0], out[1]);

47                 }

48                 return out;

49             }

50             else if(sum < target)

51             {

52                 left++;

53             }

54             else

55             {

56                 right--;

57             }

58         }

59 

60         out[0] = out[1] = 0;

61         return out;

62     }

63 };
View Code

 Solution 2: Use std::map ==> O(nlogn) (std::map::find is a O(logn) operater )

 1 class Solution {

 2 public:

 3     vector<int> twoSum(vector<int> &numbers, int target)

 4     {

 5         int len = numbers.size();

 6         vector<int> out(2);

 7         map<int, int> m;

 8         

 9         for(int i=0; i<len; i++)

10         {

11             map<int, int>::const_iterator it = m.find(target - numbers[i]); 

12             if( it != m.end())

13             {

14                 out[1] = i + 1;

15                 out[0] = it->second + 1;

16                 return out;

17             }

18             m.insert(pair<int, int>(numbers[i], i));

19         }

20     }

21 };
View Code

 

Solution 3: Magic math method ==> O(nlogn) (std::map[] is a O(logn) operater )

if x*(target -x) == y*(target-y)

then: x ==y OR x + y ==target

 1 #include <vector>

 2 #include <iostream>

 3 #include <map>

 4 using namespace std;

 5 

 6 class Solution {

 7 public:

 8     vector<int> twoSum(vector<int> &numbers, int target)

 9     {

10         int len = numbers.size();

11         vector<int> out(2);

12 

13         map<long long, int> mapping; // default is 0

14         // cout << mapping[0] << endl; // 0 is printed

15 

16         for(int i=0; i<len; i++)

17         {

18             long long mul = (target - numbers[i]) * numbers[i];

19             

20             if(mapping[mul] > 0)

21             {

22                 if(numbers[i] + numbers[mapping[mul]-1] == target)

23                 {

24                     out[0] = mapping[mul];

25                     out[1] = i + 1;

26                     return out;

27                 }

28             }

29             else

30             {

31                 mapping[mul] = i + 1;

32             }

33         }

34 

35         out[0] = out[1] = 0;

36         return out;

37     }

38 };
View Code

 

Solution 4: Use Hash Map ==> O(n)

This method is referenced from Zhihu.com, and the original method is using HashSet(in C++11 or later is std::unordered_set). However, I don't know how to output index with it. After chanaging to use HashMap(in C++11 or later is std::unordered_map), it's accepted.

 1 class Solution {

 2 public:

 3     vector<int> twoSum(vector<int> &numbers, int target)

 4     {

 5         int len = numbers.size();

 6         vector<int> out(2);

 7         unordered_map<int, int> map;

 8         

 9         for(int i=0; i<len; i++)

10         {

11             unordered_map<int, int>::const_iterator fd = map.find(target - numbers[i]); 

12             if( fd != map.end())

13             {

14                 out[1] = i + 1;

15                 out[0] = fd->second + 1;

16                 return out;

17             }

18             map.insert(pair<int, int>(numbers[i], i));

19         }

20     }

21 };
View Code

 

你可能感兴趣的:(LeetCode)