问题描述(无序)
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定: nums = [2, 7, 11, 15], target = 9
因为 :nums[0] + nums[1] = 2 + 7 = 9
返回 :[0, 1]
链接:https://leetcode-cn.com/problems/two-sum
解法一:暴力遍历
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
length = len(nums)
for i in range(length):
for j in range(i + 1, length):
if nums[i] + nums[j] == target:
return i, j
当时看到这一题第一个想法就是使用遍历,使用两个For循环,这样遍历一次时间复杂度为
O
(
n
)
O(n)
O(n),在第二个for中又进行了遍历,总体时间复杂度为
O
(
n
2
)
O(n^2)
O(n2),空间复杂度为
O
(
1
)
O(1)
O(1)
运行结果:
执行用时 : 7748 ms, 在所有 Python3 提交中击败了5.00%的用户
内存消耗 :13.4 MB, 在所有 Python3 提交中击败了98.88%的用户
解法二:两遍哈希
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
dictionary={}
for index, elem in enumerate(nums):
dictionary[elem]=index
for index, elem in enumerate(nums):
temp=dictionary.get(target-elem)#判断是否有键值要使用get
if temp is not None and temp!=index:
return index, temp
解法二是使用空间换取时间,因为需要查找这就天生使用哈希表比较好,使用字典模拟哈希表,其中字典的键等于原始list的值,这样直接可以使用get来判断是否存在适合的值,时间复杂度为 O ( n ) O(n) O(n)(我们把包含有 n n 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) 降低到 O ( 1 ) O(1) O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O ( n ) O(n) O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O ( 1 ) O(1) O(1)。
==注意:==要判断
哈希表:{https://blog.csdn.net/u011109881/article/details/80379505}
运行结果
执行用时:44ms,在所有 Python3 提交中击败了97.99%的用户
内存消耗:14.9MB,在所有Python3提交中击败了?%的用户
解法三:一遍哈希
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
dictionary={}
for index, elem in enumerate(nums):
if dictionary.get(target-elem) is not None and dictionary.get(target-elem)!=index:
return dictionary.get(target-elem),index
dictionary[elem] = index#这一段如果放在判断之前,在有两个相同元素出现的时候会返回null,如[3,3]target:6
我们可以一次完成。在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。
时间和空间复杂度和解法二一样
运行结果
执行用时 :48 ms, 在所有 Python3 提交中击败了95.05%的用户
内存消耗 :14.1 MB, 在所有 Python3 提交中击败了54.30%的用户
问题描述(有序)
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
解法:双指针
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
length=len(numbers)
first=0
last=length-1
while True:
if (numbers[first]+numbers[last])==target:
break
elif (numbers[first]+numbers[last])<target:
first=first+1
elif (numbers[first]+numbers[last])>target:
last=last-1
return first+1, last+1
我们使用两个指针,初始分别位于第一个元素和最后一个元素位置,比较这两个元素之和与目标值的大小。如果和等于目标值,我们发现了这个唯一解。如果比目标值小,我们将较小元素指针增加一。如果比目标值大,我们将较大指针减小一。移动指针后重复上述比较知道找到答案。
运行结果
执行用时 :44 ms, 在所有 Python3 提交中击败了97.80%的用户
内存消耗 :13.3 MB, 在所有 Python3 提交中击败了98.22%的用户