原题
题目大意及思路
- 题目大意: 给了一个数组
nums
及一个数target
,要求找出数组nums
中两个元素,使得两个元素相加的和为target
,按顺序存储两个元素的下标到动态数组中并返回该数组。 - 思路:
①用结构体存储下数组的值以及坐标,放入动态数组v
中。由于题中条件保证了只有一个解,那么不存在有解如:一个解元素m
(数组nums
中存在多个m
),一个解元素n
,因此不必担心重复元素的下标选择问题。
②将v
排序,使用双指针思想,得到解。
代码
class Solution {
public:
struct node{
int value,index;
};
static bool cmp(node a,node b){
return a.value<b.value;
}
vector<int> twoSum(vector<int>& nums, int target) {
vector<node> v;
for(int i=0;i<nums.size();i++) v.push_back({nums[i],i});
sort(v.begin(),v.end(),cmp);
int i=0,j=v.size()-1;
vector<int> ans;
while(i!=j){
if(v[i].value+v[j].value==target){
ans.push_back(v[i].index);
ans.push_back(v[j].index);
break;
}
else if(v[i].value+v[j].value<target) i++;
else j--;
}
return ans;
}
};
运行截图
收获
- 我的解法因为使用了结构体+动态数组,内存方面实在是不佳。看了官方解法:使用哈希表。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable;
for (int i = 0; i < nums.size(); ++i) {
auto it = hashtable.find(target - nums[i]);
if (it != hashtable.end()) {
return {it->second, i};
}
hashtable[nums[i]] = i;
}
return {};
}
};
思路为:在遍历每个元素的时候,就从哈希表就用迭代器和find()
函数查找是否存在target - nums[i]
,若不存在,则在哈希表中记录下此时的映射关系(上面有解释过,不必担心有重复的元素时下标被覆盖,因为当有重复的元素时,要么有且只有两个重复元素即解,要么解中不会出现该重复元素),若存在,则可以返回答案,此时答案为{it->second, i}
。(因为遍历是按照下标顺序来的,所以当迭代器找到时,找到的元素一定在目前i
的前面,若在后面的话映射表还未存入)