LeetCode 热题 HOT 100 第一天 1. 两数之和 简单题 用python3求解

题目地址

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

在这里插入图片描述
法1:

#方法一
#用 Python 中 list 的相关函数求解
#解题关键主要是想找到 num2 = target - num1,是否也在 list 中,那么就需要运用以下两个方法:
#num2 in nums,返回 True 说明有戏
#nums.index(num2),查找 num2 的索引
#执行通过,不过耗时较长,共 1636ms。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        lens = len(nums)
        j=-1
        for i in range(lens):
            if (target - nums[i]) in nums:
                if (nums.count(target - nums[i]) == 1)&(target - nums[i] == nums[i]):#如果num2=num1,且nums中只出现了一次,说明找到是num1本身。
                    continue
                else:
                    j = nums.index(target - nums[i],i+1) #index(x,i+1)是从num1后的序列后找num2(即从i+1的位置开始找target - nums[i]的索引。不然,如果没有i+1这一项,示例3的“nums = [3,3], target = 6”这种情况会有误,默认返回的会是第一个3的索引0,则[i,j]==[0,0],即j不满足j>0的条件,所以会return []。但如果有了i+1,那么输出的会是从i+1位置开始查到得到的3,即不包括第一个3,此时输出的j是1)                
                    break
        if j>0:
            return [i,j]
        else:
            return []

法2:

#方法二
#用 Python 中 list 的相关函数求解
#解题思路是在方法一的基础上,优化解法。
#想着,num2 的查找并不需要每次从 nums 查找一遍,只需要从 num1 位置之前或之后查找即可。
#但为了方便 index 这里选择从 num1 位置之前查找。
#执行通过,耗时缩短一半多,共 652ms。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        lens = len(nums)
        j=-1
        for i in range(1,lens):
            temp = nums[:i]
            if (target - nums[i]) in temp:
                j = temp.index(target - nums[i])
                break
        if j>=0:#注意方法二j是可以为0的,但方法一的j一定不能为0。方法一的i可以为0,方法二的i一定大于0
            return [j,i]#注意这里是j在前,i在后
        #关于nums[:i],假设L=len(nums)
        #nums[:3]表示取前3个元素,即索引值为0,1,2的元素
        #nums[3:]表示取后3个元素,即索引值为L-1,L-2,L-3的元素

法3:(这个方法不错)

#方法3
#参考了大神们的解法,通过哈希来求解,这里通过字典来模拟哈希查询的过程。
#个人理解这种办法相较于方法一其实就是字典记录了 num1 和 num2 的值和位置,而省了再查找 num2 索引的步骤。
#通过字典的方法,查找效率快很多,执行速度大幅缩短,共 88ms。
#字典是键值对的形式,如{key1:value1,key2:value2},key和value一一对应
#以下注释以nums=[3,1,3],target=6为例
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashmap={}
        for ind,num in enumerate(nums):
            hashmap[num] = ind #ind分别为0,1,2,haspmap[3]=0,haspmap[1]=1,haspmap[3]=2
#这里print出来的哈希表为:{3: 2, 1: 1},而不是{3: 0, 1: 1,3:2}
#这是因为字典的一个重要性质是,键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。
#所以这里的哈希表后面的3覆盖了前面的3
        for i,num in enumerate(nums):#i是从nums里面去查找元素的,所以i能找到第一个3
            j = hashmap.get(target - num)
            #j是在hashmap{3: 2, 1: 1}里查找元素的,所以j是找到第二个3
            #hashmap.get()方法获取指定 key 对应对 value。
            if j is not None and i!=j:
                return [i,j]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值