题目描述:给出一个整数数组,如果有两个数之和等于某一指定的数字,则返回这两个数的下标。例如
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
注意:数组中的每个元素不能使用超过两次。
思路:利用哈希表映射元素和元素索引之间的关系。把搜索表的复杂度从O(n)降低到近似O(1),近似的意思是指如果哈希表中有相同的元素发生冲突,那么最差的情况可能也是O(n)。
方法1:two-pass哈希表
建立两个循环:第一个循环把数组中的值和相应的索引加入哈希表O(n),第二个循环遍历数组中的每一个元素,如果该元素相对于指定数字的补集在哈希表中,就返回下标。遍历一次的复杂度也是O(n)。
整体的时间复杂度O(2n+1)=O(n),空间复杂度O(n)。
代码:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
dict1 = {}
list1 = []
for i in range(0,len(nums)):
dict1[nums[i]] = i
for j in range(0,len(nums)):
if target-nums[j] in dict1 and nums[j]!=target-nums[j]:
list1.append(dict1[nums[j]])
list1.append(dict1[target-nums[j]])
del dict1[nums[j]]
del dict1[target-nums[j]]
return (list1)
这样写的代码并没有通过测试,原因是测试例子中存在[3,3]这样的数组,而构建字典会出现重名的现象。不知道怎么解决。
方法2:利用one-pass哈希表
方法2和方法1类似,就是在一边建立哈希表的时候一边查找补集是否出现在哈希表中,把索引值对应的数字的补集作为字典的键,索引值本身作为键值,从数组的初始位置遍历元素,如果不在该元素不在字典中,就把它的补集当成键,索引值本身当做键值加入字典中,这样接下来索引到这个数的补集的时候,对应的键值就是该数在数组中的位置,也就是返回数组的第一个元素,而补集的数字对应的索引就是返回数组的第二个元素。
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)<1:
return False
dict1 = {}
for i in range(0,len(nums)):
if nums[i] in dict1:
return [dict1[nums[i]],i]
else:
dict1[target-nums[i]]=i
至此,该题完成
哎,编程小白伤不起……