一开始看到这个题目时,最先想到的就是暴力破解法,暴力法很简单,直接检索nums里每一个x并再次查找nums中是否存在一个与target-x相等的目标值。
暴力破解:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int lenth=nums.size();
for(int i=0;i<lenth-1;i++)
{
for(int j=i+1;j<lenth;j++)
{
if(nums[i]+nums[j]==target)
{
return vector<int> {i,j};
}
}
}
return {};
}
};
执行通过,耗时360ms,内存消耗9.5MB
复杂度分析:
时间复杂度为O(n2),空间复杂度为O(1)
之后,我又想到了使用map进行查找以降低其时间复杂度。
使用map进行查找:
对nums中的每一个i,都以target-nums[i]
为key,i为value来构建一个map,再遍历数组nums对每一个nums[j]
在map中查找,若找到一个key值为nums[j]
则输出i,j。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
map<int,int> num_map;
vector<int> twonum;
for(int i=0;i<nums.size();i++)
{
num_map[nums[i]]=i;
}
for(int i=0;i<nums.size();i++)
{
if(num_map.count(target-nums[i])&&num_map[target-nums[i]]!=i)
{
twonum.push_back(i);
twonum.push_back(num_map[target-nums[i]]);
return twonum;
}
}
return twonum;
}
};
执行通过,耗时12ms,内存消耗10.9MB
复杂度分析:
时间复杂度为O(nlogn),空间复杂度为O(n)
暴力破解耗时太长,为了对程序运行的时间复杂度进行优化,参考大佬们的讲解,使用哈希表降低其时间复杂度。遍历数组nums,对其中每个值都有一次判断哈希容器map中是否存在target-nums[i]
的键值,若存在则找到了符合要求的两个值,输出其对应键值;若不存在则将当前的(nums[i],i)
存入map中,继续遍历直到找到为止;如果直到最终仍未找到则抛出异常。也可以使用两次迭代,在第一次迭代中将nums中每个元素的值和其索引都存入表中,之后再在第二次迭代中,检查每个元素所对应的target-nums[i]
是否存在在表中,若存在则输出两个值的索引,反之则抛出异常。
两遍哈希表:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int,int> num_map;
for(int i=0;i<nums.size();i++)
{
num_map[nums[i]]=i;//将nums中的每个元素的值和其索引都存入表中
}
for(int i=0;i<nums.size();i++)
{
if(num_map.find(target-nums[i])!=num_map.end()&&num_map[target-nums[i]]!=i)//num_map中存在与target-nums[i]对应的键值,且不为i
{
return vector<int>{i,num_map[target-nums[i]]};//输出两个值
}
}
return vector<int>();
}
};
执行通过,耗时16ms,内存消耗10.4MB
复杂度分析:
时间复杂度为O(n),空间复杂度为O(n)
一遍哈希表:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int,int> num_map;
for(int i=0;i<nums.size();i++)
{
if(num_map.find(target-nums[i])!=num_map.end())//num_map中存在对应的键值
{
return vector<int>{num_map[target-nums[i]],i};//输出时i为表的最大的元素,之前添加进去的元素均小于i
}
num_map[nums[i]]=i;//num_map中不存在对应的键值时,将(nums[i],i)存入表中
}
return vector<int>();
}
};
执行通过,耗时8ms,内存消耗10.3MB
复杂度分析:
时间复杂度为O(n),空间复杂度O(n)