题目分析
给定一个整数数组nums和一个目标值target,请你在数组中找到两个和为目标值的整数,并返回他们的下标。你可以假设每个数组中只包含一种答案,但是每个元素只能使用一遍。
三种方法
在编程的过程中我们会受到两个因素的限制:时间和空间,往往这里两种因素我们只能选择其一,下面列出了三种不同方法来解决这个问题。
暴力解法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int>a;
int i,j;
for(i=0;i<nums.size()-1;i++){
int t;
t=target-nums[i];
for(j=i+1;j<nums.size();j++){
if(nums[j]==t){
a.push_back(i);
a.push_back(j);
break;
}
}
}
return a;
}
};
这种方法思路比较简单,就是依次的找出每个元素的匹配值( t=target-nums[i])是否在数组中。
一遍哈希
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i]) != m.end()) //m中存在对应的键值
return {m[target-nums[i]] , i}; //m[target-nums[i]]为已经加入map的元素的索引,所以小于本轮循环中的i,放在前面
m[nums[i]]=i; //向map中添加元素
}
return {};
}
};
代码摘抄至此处
这种方法加入了哈希表,利用了unordered_map,它是利用哈希表进行组织的,而map内部采用了自平衡的BST(二叉搜索树)的数据结构。
两遍哈希法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
m[nums[i]] = i; //把所有的元素添加到map里
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i]) != m.end() && m[target-nums[i]] != i) //如果m中存在对应的键值,而且不是a当前的元素。
return {i , m[target-nums[i]]};
}
return {};
}
};
代码摘抄至此处
与第一种方法相比,后面的两种在时间上有显著的提高,但是这是以牺牲内存为代价的,所以具体使用哪一种方法,还是要针对题目而定。