LeetCode1: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

解法一

求两个数的和为target的数,但是需要返回的是下标而不是两个数,所以不能先对数组排序再从两边开始遍历。

但是借助于map可以按照上面的思路实现,map中的元素会自动按照key进行排序,所以可以将数组中的元素值作为map的键,数组中元素的下标作为map的值,这样找到符合要求的键后获取它的值就可以了。需要注意的是数组中的元素可能会出现重复,所以需要使用multimap。
runtime:28ms
下面是实现的代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        multimap<int,int> maps;
        int length=nums.size();

        //首先用vector对map进行初始化,map中元素的第一个分量是vector中的元素值,第二个分量是vector的下标
        for(int i=0;i<length;i++)
        {
            maps.insert(pair<int,int>(nums[i],i));
        }
        map<int,int>::iterator firstIter=maps.begin();
        map<int,int>::iterator lastIter=--maps.end();//注意map的迭代器不支持operator+,只支持operator++这种
        //根据map中元素的第一个分量对map进行遍历
        while(firstIter->first<=lastIter->first)
        {
            if((firstIter->first+lastIter->first)>target)
            {
                lastIter--;

            }
            else if((firstIter->first+lastIter->first)<target)
            {
                firstIter++;
            }
            else
            {
                if(firstIter->second>lastIter->second)
                {
                    result.push_back(lastIter->second+1);
                    result.push_back(firstIter->second+1);
                }
                else
                {
                    result.push_back(firstIter->second+1);
                    result.push_back(lastIter->second+1);
                }
                break ;
            }
        }
        return result;

    }
};

解法二

提交完上面的代码后查看了下Discuss看还有没有一些高效的解法,发现有一种解法很有趣,也是使用map但是他使用的是unordered_map,即基于hash table的map,并且他使用的不是map自动排序的特性而是使用map查询速度快的特性。以前一直不知道stl中的查询函数find的用途,现在见识到了,查询算法和排序算法一样有效。
runtime:16ms
代码如下:

class Solution {
public:   
     vector<int> twoSum(vector<int>& nums, int target) 
     {
         unordered_map<int ,int> maps;

         //将数组中的元素依次插入map中,但是每次插入时判断map中是否已经存在与其相加和为target的元素,如果存在就返回,
         //如果不存在,就将这个元素和它的下标插入map中,由于使用的是unordered_map,它是基于hash table实现的,所以它的插入
         //和查询效率都是非常高效的。
         for(int i=0;i<nums.size();i++)
         {
             auto iter=maps.find(target-nums[i]);
             if(iter!=maps.end())
                return {iter->second+1,i+1};

              maps[nums[i]]=i;
         }

     }
};

你可能感兴趣的:(LeetCode)