力扣001 两数之和
题干
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
解析
1、暴力破解——双循环
主要想法:外循环遍历全部元素,确定第一个数 num1。确定num1后,从num1的后一个元素开始寻找是否存在满足条件的num2(target - num1),若存在,则输出两个数的索引,若不存在,则进入下一次外循环。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
n = len(nums)
for i in range(n):
num1 = nums[i]
num2 = target - num1
if num2 in nums[i+1:]:
return i, nums[i+1:].index(num2)+i+1
这里还有一个需要注意的点,就是我们遍历列表时其实是有两种遍历法的。一种是通过索引遍历,另一种是直接遍历元素。具体是指:
# 通过索引遍历
for i in range(len(nums)):
# 直接遍历元素
for num in nums:
本题建议通过索引来遍历。
有的人可能会说,我完全可以先找到满足要求的两个具体元素,然后通过list.index(num)语句来找到索引。
这种想法对于大多数情况都没问题,但是举个例子:
target = 6
nums = [3, 3]
这种情况下,如果通过寻找 3 的索引来解题,那么输出就会是 0,0。显然错误。
出现这种问题的原因在于,列表的index()方法返回的是从左往右找到的第一个元素的索引,所以当我们要找的两个元素值相等时,就会返回两个相同的索引。
当然,这种情况也可以优化一下,比如取得num1索引后从nums中删除num1,然后再获取num2的索引,最后对num2做一个判断,可能需要+1,
只是这样做显然没有通过索引来遍历列表来的简单。
2、双指针——排序
做数组(列表)题时,经常会用到双指针法,本题的想法是先对原数组做一次排序,然后用指针分别前向后向遍历数组,找到符合要求的元素。
我们通过指针 i 和 指针 j 分别指向数组的首元素和尾元素,将两个元素之和与target进行比较,若target较大,说明需要将 指针i 后移(i 越后移元素值越大);若target较小,则将 指针j 前移(j 越前移元素值越小)。直到找到满足的 i 与 j。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
nums_temp = nums.copy()
nums_temp.sort()
i = 0
j = len(nums) - 1
while i < j:
if nums_temp[i] + nums_temp[j] > target:
j -= 1
elif nums_temp[i] + nums_temp[j] < target:
i += 1
else:
break
x = nums.index(nums_temp[i])
nums.remove(nums_temp[i])
y = nums.index(nums_temp[j])
if x <= y:
y += 1
return x, y
通过这种方法同样也有需要注意的点,因为我们最后找到的 i 和 j,是在排序后的数组中的索引,并不是题目的直接答案,我们能得到的,只是nums[i]和nums[j]这两个元素值,具体这两个数在原数组中的索引,需要到原数组中寻找,因此我们需要保留原数组。
而通过元素寻找索引的注意事项与方法1中提到的一样。
3、哈希表
与双指针一样,哈希表在数组题中用到的也很多,而且Python内置的字典数据类型就是一个天然的哈希表。由于哈希表查询的速度极快——O(1),因此可以用哈希表来优化解题。
使用哈希表的一个关键之处在于如果确定key和value的对应关系。
本题的key为元素值,value为该元素在列表中的索引。
具体来说,我们遍历nums,确定num1,确定num1之后,判断num2是否存在于哈希表中,如果存在,说明找到了num2;如果不存在,则将num1于num1的索引作为键值对保存进哈希表中。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hash_map = dict()
for i in range(len(nums)):
if target - nums[i] in hash_map.keys():
return hash_map[target - nums[i]], i
hash_map[nums[i]] = i
通过哈希表解本题需要注意输出的顺序(return的顺序),很容易搞反
634

被折叠的 条评论
为什么被折叠?



