题解 | #和为S的两个数字#
题目:https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b
牛客题解官思路。
最直接的想法是两次for循环遍历查找,将数组所有的二元组合枚举一遍,看看是否是和为目标值,不过时间复杂度较高。
法一:哈希方法
step 1:构建一个哈希表,其中key值为遍历数组过程中出现过的值,value值为其相应的下标,因为我们最终要返回的是下标。
step 2:遍历数组每个元素,如果目标值减去该元素的结果在哈希表中存在,说明我们先前遍历的时候它出现过,根据记录的下标,即得到结果。
step 3:如果相减后的值没有在哈希表中,说明先前遍历的元素中没有它对应的另一个值,那我们将它加入哈希表,等待后续它匹配的那个值出现即可。
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param array int整型一维数组
# @param sum int整型
# @return int整型一维数组
#
class Solution:
def FindNumbersWithSum(self , array: List[int], sum: int) -> List[int]:
# res=[]
# mydict={}
# for i in range(len(array)):
# temp=sum-array[i]##在哈希表中查找sum-array[i]
# if temp not in mydict:#temp不在mydict里面,就把array[i]加进去
# mydict[array[i]]=i
# else:
# res.append(array[i])
# res.append(temp)
# break
# return res
#因为字典的键设置的是数组里面的元素,所以对于数组中有重复元素的这种情况。会有点问题。
时间复杂度:O(n),其中n为数组长度,遍历一次数组
空间复杂度:O(n),哈希表最大空间为n
法二:双指针。 上面方法的缺陷是没有利用到升序数组。可以用双指针对撞查找。
step 1:准备左右双指针分别指向数组首尾下标。
step 2:如果两个指针下的和正好等于目标值sum,则找到了所求的两个元素下标。
step 3:如果两个指针下的和大于目标值sum,右指针左移;如果两个指针下的和小于目标值sum,左指针右移。
step 4:当两指针对撞时,还没有找到,就是数组没有。
if array==[]:#特殊情况
return []
res=[]
left=0
right=len(array)-1
while left!=right:#也可以用小于号
if array[left]+array[right]>sum:
right=right-1
elif array[left]+array[right]<sum:
left=left+1
else:
res.append(array[left])
res.append(array[right])
break
return res
时间复杂度:O(n),其中n为数组长度,左右指针共同遍历一次数组
空间复杂度:O(1),常数个变量