原题:                          https://leetcode.com/problems/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

 

I.思路:  队列,flag,hash

本题可以划分为两块儿:

  1. 怎么找到满足条件的两个数;
  2. 怎么输出它俩的index。

注意到,本题一定有解,而且有唯一解,这就大大简化了思路。

对于1,计算复杂度为O(n)的方法是,先排序,然后队头队尾都有个flag,当其和大于target,说明大了,把队尾flag前移,其和小于target,说明小了,把队头flag后移,直到等于的情况,这样就找到了那两个数。

对于2,显然需要记住每个数的index,方法就是用hash函数,用map来实现。

 

特殊情况:

队列里有两个或更多相同数字。如果相同数字个数大于2,说明不是要找的数,否则违背唯一性原则,所以不用管;如果要找的数恰好是两个相同的,会存在hash冲突,我用了个笨法,搞了两个map...

 

自己a过去的代码:

 1 #include <map>
 2 #include <algorithom>
 3 class Solution {
 4 public:
 5 
 6     vector<int> twoSum(vector<int>& nums, int target) {
 7         vector<int> result;
 8         map <int,int> name,name2; 
 9         vector<int>::iterator it,it2;
10         for(it=nums.begin();it!=nums.end();++it){
11             if (name.find(*it) == name.end())
12                 name[*it]=it-nums.begin()+1;
13             else
14                 name2[*it]=it-nums.begin()+1;
15         }
16         sort(nums.begin(),nums.end());
17         it=nums.begin();
18         it2=nums.end()-1;
19         while(it!=it2){
20             if (*it+*it2>target)
21                 it2--;
22             else if (*it+*it2<target)
23                 it++;
24             else if (*it+*it2==target){
25                 if(*it!=*it2){
26                     result.push_back(min(name[*it],name[*it2]));
27                     result.push_back(max(name[*it],name[*it2]));
28                 }
29                 else{
30                     result.push_back(min(name[*it],name2[*it]));
31                     result.push_back(max(name[*it],name2[*it]));
32                 }
33                 return result;
34             }
35         }
36     }
37 };

 

II. advance:

O(n),不排序,直接用hash搞定。核心思想:利用hash冲突的特点来找两个数,将同位冲突改为互补冲突。

自己a过去的代码2:

 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int>& nums, int target) {
 4         map<int,int> name;
 5         vector <int> result;
 6         for(int i=0;i<nums.size();++i){
 7             if (name.find(nums[i])==name.end()){
 8                 name[target-nums[i]]=i;
 9             }
10             else{
11                 result.push_back(name[nums[i]]+1);
12                 result.push_back(i+1);
13                 break;
14             }
15         }
16         return result;
17     }
18 };

 

 

III.官方solution: 

 

O(n2) runtime, O(1) space – Brute force:

The brute force approach is simple. Loop through each element x and find if there is another value that equals to target – x. As finding another value requires looping through the rest of array, its runtime complexity is O(n2).

O(n) runtime, O(n) space – Hash table:

We could reduce the runtime complexity of looking up a value to O(1) using a hash map that maps a value to its index.