题目描述
方法1-暴力循环
使用两个循环遍历数组,第一个循环从头到尾遍历数组,第二个循环从第一个循环所在的位置之后开始遍历剩余的数组,找到两个循环对应位置的元素之和为target,返回索引。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int len = nums.size(); //获取数祖长度
for (int i=0; i<len; i++){
for (int j=i+1; j<len; j++){
if (nums[i] + nums[j] == target)
return {i,j};
}
}
return {}; //要求每个测试数组都要有输出
}
};
时间复杂度:O(N2) 最坏情况下两个数组中所有数都被遍历一遍
空间复杂度:O(1)
方法2-哈希表
方法1的时间复杂度较高的原因是寻找 target - x的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。
使用哈希表,可以将寻找 target - x 的第二次遍历时间复杂度降低到从 O(N) 降低到 O(1)。
这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable; //创建哈希表
int len = nums.size(); //获取叔祖长度
for (int i=0; i<len; i++){
// 判断当前target-num[i]是否已经在哈希表中
//map中find()函数的参数是key,返回的是查找到位置的迭代器,如果找不到就返回end()位置的迭代
auto j = hashtable.find(target - nums[i]);
if (j != hashtable.end()){
return {j->second, i};
}
hashtable[nums[i]] = i;
}
return {};
}
};
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashtable = {} #用字典存放哈希表
for i in range(len(nums)):
if (target - nums[i]) in hashtable:
return [hashtable[target-nums[i]], i]
hashtable[nums[i]] = i #更新哈希表
return []
时间复杂度:O(N),对于每一个元素 x,我们可以 O(1)地寻找 target - x。
空间复杂度:O(N),哈希表的开销