您的位置:首页 > 其它

LeetCode修仙:Two Sum详解

2018-01-14 19:53 330 查看
不重要:

最近天天玩吃鸡,优点颓废,好好坚持刷一下LeetCode,本博客力求一题多解,从时间复杂度上完成自我代码修养的提高。

problem:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].


方法1:

分析:

首先我们知道:无需把数组中所有的符合要求的下标组列出来,只需要一组,并且与顺序无关。我们很容易想到一种思路如下图:



我们可以从第一个蓝色开始:一个一个跟后面的比对;继而黄色;以此类推...发现有数据对满足和为:target.就结束寻找;并返回两者下标;

代码如下:

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> answer;
int len=(int)nums.size();
for(int i=0;i<len-1;i++)
for(int j=i+1;j<len;j++)
{
if((nums[i]+nums[j])==target)
{
answer.insert(answer.end(), i);
answer.insert(answer.end(), j);
break;
}
}
return answer;
}
};


运行效果:






可能错误:

reference binding to null pointer of type 'value_type'

注意:vector的赋值分两个,一者在初始化的时候;一者在后续插入。由于代码中answer的初始化未进行,所以,如果用

answer[0]=i;
answer[1]=j;


替换

answer.insert(answer.end(), i);
answer.insert(answer.end(), j);

则会出现上述错误;

方法2:

上述的方法虽然可以通过,但是我们不难发现,时间成本还是比较高,时间复杂度是O(N^2),显然不是最优秀的解法,于是,上网搜索更好的思路发现了新大陆:hash_map,通过这种Key+value的快速搜索结构体,我们可以进一步加快我们的程序;

新版的C++ 11中hash_map都是unordered_map了,所以这里只说unordered_map,但也要区分它和map的区别:

运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。

占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

unordered_map的用法:

开头:

#include<tr1/unordered_map>//加上tr1库名,
using namespace std::tr1;//加上命名空间


初始化:


unorder_map<int, string> mapStudent;
mapStudent[1] =  “student_one”;
mapStudent[2] =  “student_two”;
mapStudent[3] =  “student_three”;


查找:
    若有unordered_map<int, int> mp;查找x是否在map中
    方法1:  若存在  mp.find(x)!=mp.end()
    方法2:  若存在  mp.count(x)!=0

插入:

map.insert(map::value_type(1,"Raoul"));


遍历:

unordered_map<int, string>::iterator  iter;map<int, string>::iterator  iter;
for(iter = mapStudent.begin();  iter != mapStudent.end();  iter++)

{...}


利用Value查找Key&&删除:

map<int, string>::iterator iter;

iter = mapStudent.find(1);

mapStudent.erase(iter);


代码如下:

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> answer;
unordered_map<int,int> hash;
for(int i=0; i<nums.size(); i++)
{
int NumToFind=target-nums[i];
if(hash.find(NumToFind) != hash.end())
{
answer.push_back(hash[NumToFind]);
answer.push_back(i);
return answer;
break;
}
else
hash[nums[i]]=i;
}
}
};


代码注解:

你可能觉得hash对象并没有被初始化:这不是问题:因为这里比较巧妙,hash一开始确实是空的:不过在每一次循环中,最后都会执行:

hash[nums[i]]=i;

所以hash是从头部开始进入的:比如:【2,6,9,8,3,4】target=5

最后输出的是第五层for循环中(i=4),发现NumToFind=5-3=2时候,从hash中找到了2,这样得出来的,这也解释了answer中为什么先push进去的不是i;所以这里有点巧妙,也可以说:有点难理解,是一个“反哺”的机制,挺有意思的;

运行结果:



总结:

这样,时间从189ms提高到了9ms,十分满足,而且也顺便学了unordered_map的用法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LeetCode Two Sum