力扣001 两数之和

力扣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的顺序),很容易搞反

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值