Python刷LeetCode之题目#1两数之和

写在前面的话

从今天起,就正式开启自己的刷题之路了。一方面通过刷题来训练自己的思维能力、代码能力,另一方面,也可以很好地弥补自己知识结构的不足,毕竟总是看教材两天就烦了。。。

题目#1—两数之和

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

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

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

原题见:两数之和

我自己的思路

既然来写博客,当然是和大家一起分享思路的,所以自己怎么想的就怎么写,哪怕我的方法可能很蠢。。。

拿到这道题,很自然地,恐怕绝大多数的人的反应都是一样的,就是两个for循环,暴力破解法。从第一个开始,判断后面的每一个数和它相加是否能够得到目标值,然后再从第二个开始,以此类推。。。这样的思路恰好是题目要求的 O(n2)的算法复杂度。

所以我的代码就是这么写的:

import numpy as np
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in range(len(nums)-1):
            for j in np.arange(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i,j]
                else:
                    continue

虽然通过了,但是执行用时和内存消耗都惨不忍睹。。。分析以上代码的不足:

  1. 双循环的查找方法算法复杂度太高;
  2. 第二个for循环直接用range(i+1, len(nums))就可以,非要加一个numpy,自然加大了内存消耗和执行用时;
  3. 可以取消else的内容;
  4. 为确保程序安全结束,最后应该有一个 return [];
  5. len(nums)计算了两次,所以可以计算一次然后分配内存保存成一个变量,后面继续调用,速度比每次都计算要快;

没错,我的代码就是这么失败,但我一直有一个观点,唯有敢于承认失败,才能终止失败。失败之后发现问题,总结问题,才能有所提高!

现在看这5个问题(当然如果我还有什么问题大家可以提出来指正我嗯),其中后4个,都是治标不治本,即便我修正了,对算法的性能也没有本质的提升,所以,在自己的程序性能并不好的时候,一定要去看看大神们都是怎么写的,多学习,多借鉴大神们的思路,才能快速成长!

官方推荐的代码

以下是LeetCode官方推荐代码,其链接为:LeetCode题目一官方代码

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            if target - num in hashtable:
                return [hashtable[target - num], i]
            hashtable[nums[i]] = i
        return []

它是用哈希表完成的!

哈希表,又称散列表,Python里实现的时候把这个东西叫字典,以键值对的形式来实现,一个键名对应一个值,可以快速查找对象。关于Python里字典具体都有哪些用法这里就不赘述了,不了解的大家可以通过其他渠道学习一下。

字典这个东西,我自己在学习Python的编程的时候,也是学到过的,也知道用它可以提高检索速度,但是真的遇到问题编程的时候,就只知道一个for循环,所以本质上还是不知道,不足够熟悉,不足够了解。

现在我们分析这段代码,它首先建立一个空字典,然后对这个数组开始循环(只循环一次当然会快):判断目标值减去当前值后的数值,是否在字典里,第一次循环时字典是空的当然不在,所以它就把数组中的数值作为键,把数值在数组中的位置索引作为键对应的值,插入到了字典中。直到某一次循环,找到了这个数值,然后直接输出相应的值和索引即可。

我看完之后的第一反应就是,这个算法太秒了,感觉自己好蠢!!!

总结

当我们想从一个数组中查找两个,或某几个有关系的元素时,可以考虑使用哈希表;另外,这个题目中官方代码所使用的这种边插入键值对、边进行检索的方式值得学习,这种方式简化了1个for循环不说,还让整个检索过程变得十分巧妙,大大提高了执行速度。

最后

希望自己可以坚持下去,也欢迎大家留言和我一起讨论题目和代码,可以和大家一起持续进步,加油!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值