题目
- 输入:整数数组 nums 目标值 target
- 输出:数组中和为目标值的那 两个 整数的数组下标
- NOTE:假设每种输入只会对应一个答案。
不能重复利用这个数组中同样的元素
法一:暴力解法
vector<int> TwoSum(vector<int> &nums,int target){
vector<int> ret;
for(int i=0; i<nums.size()-1; i++){
for((int j=i+1; j<nums.size(); j++){
if(nums[i]+nums[j]==target){
ret.push_back(i);
ret.push_back(j);
break;
}
}
}
return ret;
}
时间复杂度:O(n²) 两重for循环
空间复杂度:O(1) 只用存储ret代码过程体验:
- 开始的时候想用范围for,但是发现需要返回数组下下标,而范围for得到的是size_t类型不能用于下标返回
- 之后打算使用迭代器,但是迭代器类型对于本题是vector<int>::iterator不能作为下标返回
法二:两遍哈希表
vector<int> TwoSum(vector<int> &nums, int target){
vector<int> ret;
map<int,int> one_hash;
//创建哈希表,其中key是数组的元素,value是序号
for(int i =0; i< nums.size(); i++){
one_hash[nums[i]]=i;
}
//哈希表寻找对应的值
for(int i =0; i<nums.size(); i++){
//这个表示哈希表存在差值同时不是数组自身
if(one_hash.count(target-nums[i])!=0
&& one_hash[target-nums[i]]!=i) {
ret.push_back(i);
ret.push_back(one_hash[target-nums[i]]);
break;
}
}
return ret;
}
时间复杂度:O(n) 哈希表查找为O(1),对n个元素列表遍历两次
空间复杂度:O(n) 额外空间存储哈希表的n对元素特别注意事项:
- if语句很重要,其中的两个想与的条件的顺序非常重要,必须判断存在在前
原因:当判断是否是自身在前的话
如果不存在,会先插入到对应的哈希表中,插入内容是:差值=0,也就是说哈希表中value为0的多了一个,而且就是目标和数组的差值,这样的话,当循环到 i=1时候能够得到,把差值又加了一个,正好组成目标值
具体过程:
第一次循环:i = 0 哈希表插入了 target-nums[0] = 0 但是其自身不行
第二次循环:i = 1 哈希表插入了target-nums[1] =0 满足了目标值,
即为 one_hash[1] + one_hash[0]
法三:一遍哈希表
vector<int> TwoSum(vector<int> &nums, int target){
vector<int> ret;
map<int,int> two_hash;
//不用单独创建哈希表
//哈希表寻找对应的值
for(int i =0; i<nums.size(); i++){
//如果存在差值,就输出了但注意顺序,总是往前找
if(one_hash.count(target-nums[i])!=0) {
ret.push_back(one_hash[target-nums[i]]);
ret.push_back(i);
break;
}
two_hash[nums[i]] = i; //插入哈希表
}
return ret;
}
时间复杂度:O(n) 哈希表查找为O(1),对n个元素列表遍历一次
空间复杂度:O(n) 额外空间存储哈希表的n对元素
注意:
由于每次遍历找差值都在之前的哈希表找,由于递增,因此输出的顺序要改变一下,先是差值下标,再是i