实现两数之和
题目描述:给定一个整数数组nums和一个目标值target,在该数组中找出和为目标值的两个数,并返回他们的数组下标。
示例:
给定 nums = [ 2,8,12 ,25 ]
给定 target = 10
寻找两个数 nums[0] + nums[1] = 2 + 8 = 10
并返回 [0,1]
方法一:暴力解法
使用两个for循环,遍历每个元素,获取每个元素与其他元素之和,并查找该值是否存在与target值相等。
class Solution1:
def twoSum(self,nums,target) :
result = []
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
result.append(i)
result.append(j)
break
return result
复杂度分析-暴力解法:
时间复杂度为
O
(
n
2
)
O(n^{2})
O(n2),两个遍历n个元素的for循环。
空间复杂度为
O
(
1
)
O(1)
O(1)
方法二:两次遍历+哈希表
对时间复杂度进行优化,我们采用一种更节省时间的方法来检查数组中是否存在两个元素的和为目标值,并返回二者索引。保存数组中每个元素与其索引相互对应的底层方法就是哈希表!
通过使用哈希表的方法可以将查找时间从
O
(
n
2
)
O(n^{2})
O(n2)降低到
O
(
1
)
O(1)
O(1),哈希表支持以近似恒定的时间进行快速查找,最不理想的情况也只是
O
(
n
)
O(n)
O(n),这种情况可以通过仔细挑选哈希函数来缓解。
class Solution2:
def twoSum(self,nums,target) :
data = {}
for i in range(len(nums)):
data[nums[i]] = i
for i in range(len(nums)):
a = target - nums[i]
if a in data:
return i,data[a]
复杂度分析-遍历两遍哈希表:
时间复杂度为
O
(
n
)
O(n)
O(n),遍历两遍n个元素的数组
O
(
n
)
O(n)
O(n),在加上哈希表的查找时间
O
(
1
)
O(1)
O(1),总的时间复杂度为
O
(
n
)
O(n)
O(n)。
空间复杂度为
O
(
n
)
O(n)
O(n),所需额外的空间取决于哈希表中存储的元素数量,该表中存储了n个元素,故为
O
(
n
)
O(n)
O(n)。
方法三:一次遍历+哈希表
我们在遍历第一次数组并添加元素索引键值对到字典中时,就可以直接进行哈希表查询,代码如下:
class Solution3:
def twoSum(self,nums,target) :
data = {}
for i in range(len(nums)):
a = target - nums[i]
if a in data:
return i, data[a]
else:
data[nums[i]] = i
使用枚举法遍历数组更优:
class Solution4:
def twoSum(self,nums,target) :
data = {}
for i,num in enumerate(nums):
if data.get(target - num) is not None:
return i,data.get(target - num)
data[num] = i
该方法减少了a变量,并且代码更简洁。
复杂度分析-遍历一遍哈希表:
时间复杂度为
O
(
n
)
O(n)
O(n), 只遍历一遍n个元素的数组
O
(
n
)
O(n)
O(n),在加上哈希表的查找时间
O
(
1
)
O(1)
O(1),总的时间复杂度为
O
(
n
)
O(n)
O(n)。
空间复杂度为
O
(
n
)
O(n)
O(n),所需额外的空间取决于哈希表中存储的元素数量,该表中存储了n个元素,故为
O
(
n
)
O(n)
O(n)。