题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解法列举:
第一种 类似二分查找
首先将首位两数之和与target相比,如果比target小,则指针head+1,若大于target,则指针head-1
时间复杂度是o(nlogn)
class Solution:
def twoSum(self,nums,target):
sorted_id=sorted(range(len(sum)),key=lambda k:num[k])
head=0
tail=len(nums)-1
sum_result=num[sorted_id[head]]+num[sorted_id[tail]]
while sorted_id!=target:
if sorted_id<target:
head+=1
elif sorted_id>target:
tail-=1
sum_result=num[sorted_id[head]]+num[sorted_id[tail]]
rerurn [sorted_id[head],sorted_id[head]]
第二种解法:暴力法 对于给定的target,遍历数组 时间复杂度O(n), 查找target == m+ n的元素,时间复杂度 O(n) 因为时间复杂度为 O(n^2) 遍历过程,未使用数据结构存储,故空间复杂度为O(1) 耗时 60ms
直接进行排序,制定两个指针,首先将第一个指针定位于第一个数,第二个指针遍历剩下的数字(一个循环)。循环结束,第一个指针指向第二位数,第二个指针接着重新遍历第一个指针后面所有的数。。依次循环,知道找到需要的数值之和。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
size = len(nums)
for i, m in enumerate(nums):
j = i + 1
while j < size:
if target == (m + nums[j]):
return [i, j]
else:
# print(i, j, m + _n, " didn't match!")
j += 1
第三种方法:用字典模拟hash
#建立空字典
首先第一个循环是产生以nums数值为key,index为values的字典_dict
第二个循环是得出target-m值多对应的标签j,最后输出。
时间复杂度为O(n) 空间复杂度为O(n) 执行时间 52 ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
_dict={}
for i,m in enumerate(nums):
_dict[m]=i
for i,m in enumerate(nums):
j=_dict.get(target-m)
if j is not None and i!=j:
return [i,j]
第四种方法:一遍字典模拟Hash
#该方法是第三种方法的简洁版,时间复杂度和空间复杂度也一样。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
_dict={}
for i,m in enumerate(nums):
if _dict.get(target-m) is not None:
return [i,_dict.get(target-m)]
_dict[m]=i
第五种 用两个for循环
时间复杂度是n*n(最简单暴力的)
class Solution(object):
def twoSum(self, nums, target):
“”"
:type nums: List[int]
:type target: int
:rtype: List[int]
“”"
if not nums:
return None
dic = {}
for i,key in enumerate(nums):
tmp = target-key
for item,value in dic.items():
if tmp == value:
return [item,i]
dic[i] = key
return None