题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
这个题目使用c++语言有两种解法,一种是暴力解决,另一种是使用哈希表
暴力方法–两遍迭代
基本思想:
- 从 0 到 nums.size() 按顺序依次执行
- 观察该元素后面所有的元素中是否存在一个nums[j]元素使得nums[i]+nums[j]==targer,若存在则返回当前元素与第一个符合条件元素的序号
- 这个算法的时间复杂度为O(n^2),效率较低
vector<int> twoSum(vector<int>& nums, int target) {
int i,j;
for(i = 0;i <nums.size(); i++){
for(j = i+1; j<nums.size(); j++ ){
if((nums[i]+nums[j])==target){
return vector<int>{i,j};
}
}
}
return vector<int>{};
}
哈希表方法
-
两遍哈希表
- 第一遍:将元素值和索引添加到哈希表
- 第二遍:检查当前元素对应的 target-nums[i] 是否在表中
- 时间复杂度O(n),空间复杂度O(n)
vector<int> twoSum(vector<int>& nums, int target){
map<int,int> hash;
int temp;
for(int i=0;i<nums.size();i++)
hash[nums[i]]=i;
/*
将元素值和索引以键值对形式添加到表中
nums[i]为键,i为值
*/
for(int i=0;i<nums.size();i++){
temp = target-nums[i];
if(hash.find(temp)!=hash.end()&&hash[t]!=i)
/*
hash.end()函数代表不存在要查找元素时返回的迭代器
要查找的元素不能是nums[i]这个元素本身
*/
return vector<int>{i,hash.find(temp)->second};
/*
first访问键值对的第一个元素key,
second访问键值对的第二个元素value
*/
}
}
return vector<int>();
}
-
一遍哈希表
- 这个方法在两遍哈希表的基础上加以改进
- 不再是完整的添加键值对后再遍历,而是一遍添加键值对一边遍历
- 例如:
添加第4对键值对,那么就在前3对中遍历寻找,不存在时才加入第4对
添加第n对键值对,那么就在前n-1对中遍历寻找,不存在时才加入第n对 - 时间复杂度O(n),空间复杂度O(n)
vector<int> twoSum(vector<int>& nums, int target){
map<int,int> hash;
int temp;
for(int i=0; i<nums.size(); i++){
temp = target - nums[i];
if(hash.find(temp)!=hash.end())
return vector<int>{hash.find(temp)->second,i};
hash[nums[i]] = i;
}
return vector<int,int>{};
}