两数之和
Posted Mr.Yao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两数之和相关的知识,希望对你有一定的参考价值。
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
方法一:暴力法
class Solution: def twoSum(self, nums, target): for i in range(len(nums)): for j in range(i+1,len(nums)): other = target - nums[i] if other == nums[j]: return [i,j] return None
遍历每一个元素x,并查找是否存在一个值与target - x相等的目标元素。(j从i+1开始,是因为如果前面的i个元素的(target - i)都不存在于该列表中,那么i之后的元素的(target - i)不存在于i之前的元素中。
算法分析:
- 时间复杂度:O(n2)。对于每个元素,我们通过遍历整个列表其它元素寻找它所对应的目标元素,耗费O(n)的时间。
- 空间复杂度:O(1)。
哈希表
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
方法二:两遍哈希表
通过以空间换取速度的方式,我们可以将查找时间从O(n)降低到O(1)。哈希表正是为此目的而构建的。
class Solution: def twoSum(self, nums, target): hashmap = {} for i,j in enumerate(nums): hashmap[j]=i for i,j in enumerate(nums): k = hashmap.get(target-j) if k is not None and k != i: return [i,k]
两次迭代,第一次迭代中我们将每个元素的值和它的索引添加到哈希表中。在第二次迭代中我们将检查每个元素对应的目标元素k=hashmap.get(target-j)是否在表中。该元素不能于i相等。假设表中有两个相等的元素,第二次索引的值会改为后一个重复元素的索引,如果第一个重复值找到了函数就结束,没找的话,第二次重复元素也肯定找不到,所以在查找中不会产生错误。
- 时间复杂度分析:O(n)。我们遍历列表两次。哈希表将查找的时间缩短为O(1),所以时间复杂度为O(1)。
- 空间复杂度:O(n)。所需的额外空间取决于哈希表中存储的元素数量,该表中存储了n个元素。
方法三:一遍哈希表
class Solution: def twoSum(self, nums, target): hashmap = {} for i,j in enumerate(nums): k = target -j if k in hashmap: return [hashmap.get(target-j), i] hashmap[j] = i
将遍历过的元素,以及它的索引加入表中,后续的元素在表中查找target - i。
复杂度分析:
- 时间复杂度:O(n)。只遍历了一次包含n个元素的列表,在表中进行的每次查找只花费O(1)的时间。
- 空间复杂度:O(n)。所需的空间取决于哈希表中的元素数量,最多存储n个元素(即遍历完没找到)。
以上是关于两数之和的主要内容,如果未能解决你的问题,请参考以下文章