leetcode---1.Two sum

来源:互联网 发布:java怎么选择权限框架 编辑:程序博客网 时间:2024/05/23 19:13

Question:

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
1.
初看该问题,首先想到的就是暴力枚举,用两个循环找出问题答案,自己测试代码为:

vector<int> twoSum(vector<int> &numbers, int target) {        vector<int> result; //保存结果        //int index1, index2;         int count = numbers.size();        int temp1;        for(int i = 0; i < count; ++i)        {            //if(numbers[i] <= target)            //if((target - numbers[i]) >= 0)            //{                temp1 = numbers[i];                for(int j = i+1;j < count; ++j)                {                    //if(numbers[j] > target)                    //if((numbers[i]-target)>0)                    //  continue;                    if((temp1+numbers[j]) == target)                    {                         result.push_back(i + 1);                        result.push_back(j + 1);                        break;                    }                }            //}        }        return result;

不幸的是leetcode对时间的要求非常严格,本题明显不想让这么简单的完成,上述解法的时间复杂度为O(N^2)。执行后是time limit executed。
2.
只好想办法优化代码 使之运行时间减少。
很容易想到的一个办法是,先求target和numbers[i]的差,然后在vector中匹配求得差

vector<int> twoSum(vector<int> &numbers, int target) {        vector<int> result; //保存结果        //int index1, index2;         int count = numbers.size();        int temp1;        for(int i = 0; i < count; ++i)        {            temp1 = target - numbers[i];            for(int j = i+1; j < count; ++j)                if(temp1 == numbers[j])                {                    result.push_back(i+1);                    result.push_back(j+1);                    break;                }        }        return result;    }

这种解法的时间复杂度仍然是O(N^2),提交后仍然通不过(很正常,思路仍然在原地)。
3. unordered_map
想了很长时间 也没有想到好解决的方法,看了discuss和在网上查了一些别人解决这道题的方法,其中一个印象深刻的是利用hash表。

vector<int> twoSum(vector<int> &numbers, int target) {        vector<int> result; //保存结果         int count = numbers.size();        int temp1;        unordered_map<int, int> numMap;        unordered_map<int, int>::const_iterator citer;        for(int j = 0; j < count; ++j)        {            temp1 = target - numbers[j];            citer = numMap.find(temp1);            if(citer != numMap.cend())            {                result.push_back(citer->second + 1);                result.push_back(j+1);                break;            }            else                numMap[numbers[j]] = j;        }        return result;    } 

使用了unordered_map之后,函数时间复杂度变为O(N)。提交后通过检查。

*unordered_map的一些说明:
1)
unordered_map的内部是使用了hash function和关键字类型的“==”运算符,因此该容器是无序的(map中使用了关键字类型“<”运算符)。
2)
哈希表的查询时间复杂度是O(1),因此unordered_map的时间复杂度也是O(1)(map的查询时间复杂度是O(logN)),但并不是unordered_map一定比map的性能好,还要考虑数据量。本题的数据本来就是无序的,因此在使用unordered_map。*
4. two pointer
这种方法需要先对原vector排序,具体代码如下:

vector<int> twoSum(vector<int>& nums, int target) {        vector<int> result;        vector<pair<int, int> > ipair;        size_t k = nums.size();        for (size_t i = 0; i < k; ++i)        {            ipair.push_back(make_pair(nums[i], i));        }        sort(ipair.begin(), ipair.end());        vector<pair<int, int>>::iterator pfound=ipair.begin(), pback = --ipair.end();        while (pfound < pback)        {            if (pfound->first + pback->first > target)                --pback;            else if (pfound->first + pback->first < target)                ++pfound;            else            {                result.push_back((pfound->second < pback->second ? pfound->second : pback->second) + 1);                result.push_back((pfound->second > pback->second ? pfound->second : pback->second) + 1);                break;            }        }        return result;    }

首先定义一个vector

0 0