题目
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].
解题思路
题目的意思很简单,给你一个数组 nums[] 和一个target值,然后在该数组里找出两个元素,使得他们加起来的和等于target值,最后返回他们的indices。
- 最粗糙的方法肯定就是暴力求解啦,不过时间复杂度为 O(n^2), 为下下策。
- 接着再想到一个方法,那就是第一步先对数组排序,时间复杂度为 O(nlog(n))。 然后第二步设两个索引 a = 0, b = n-1, 如果 nums[a] + nums[b] > target, 则 b--;如果 nums[a] + nums[b] < target, 则 a++;如果 nums[a] + nums[b] = target, 则返回 a, b 值。第二步的时间复杂度为 O(n), 所以该算法总的时间复杂度为 O(nlog(n)),该算法的代码我没有贴出来,因为很容易就能写出来。
- 第三个方法是看到讨论区有人给出自己的解法,我看到挺有意思的。他是利用了哈希表的方法。原理也很简单,首先建立一个哈希表,然后遍历一遍数组,每次遍历的时候,检查在哈希表里是否存在一个元素,使得它们两个相加等于 target 值,如果有则输出答案,如果没有则将该遍历到的元素插进哈希表中,并记录下它的 index 值。遍历的时间复杂度为 O(n), 每次遍历的时候在哈希表里检索的时间为 O(log(n)), 所以总的复杂度也为 O(nlog(n)),但是那个人说是 O(n), 他认为哈希表里检索是不需要时间的,但我认为 unordered_map 里面使用红黑树实现的,检索是有代价的,所以我觉得复杂度为 O(nlog(n))。实现代码如下:
参考代码
一、排序方法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
unordered_map<int, int> hash, temp;
//map<int, int> hash;
for(int i=0;i<nums.size() ;i++){
if(hash.find(nums[i])==hash.end())
hash[nums[i]]=i;
else
temp[nums[i]]=i;
}
sort(nums.begin() ,nums.end());
int i=0, j=nums.size()-1;
while(i<j){
if(nums[i]+nums[j]==target){
if(nums[i]==nums[j]){
ans.push_back(hash[nums[i]]);
ans.push_back(temp[nums[i]]);
}
else{
ans.push_back(hash[nums[i]]);
ans.push_back(hash[nums[j]]);
}
break;
}
else if(nums[i]+nums[j]<target)
i++;
else
j--;
}
return ans;
}
};
二、哈希方法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//Key is the number and value is its index in the vector.
unordered_map<int, int> hash;
vector<int> result;
for (int i = 0; i < nums.size(); i++) {
int numberToFind = target - nums[i];
//if numberToFind is found in map, return them
if (hash.find(numberToFind) != hash.end()) {
//+1 because indices are NOT zero based
result.push_back(hash[numberToFind] );
result.push_back(i );
return result;
}
//number was not found. Put it in the map.
hash[nums[i]] = i;
}
return result;
}
};
反思与总结
有人会认为这题那么简单,为什么还要记录下来。我认为这题虽简单,但对我还是有一定启发的。因为对 unordered_map, map 等这些数据结构,虽然我了解他们的原理和实现,但往往在实际中很少会想起使用他们,从而导致自己的算法臃肿低效,所以我们应该在实战中多多利用这些封装性强,效率高效并且使用简单的数据结构,往往他们会出奇效~
网友评论