来刷 LeetCode 啊

Posted Python之禅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了来刷 LeetCode 啊相关的知识,希望对你有一定的参考价值。

为什么要刷LeetCode,刷LeetCode吃力正常吗?看完大神们怎么说,是不是有必要给自己一个小目标,比如刷满1000题

~

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的 两个 整数。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

题目难度:easy

做这道题之前,我们先复习一下几个数据结构的特性

列表的查询复杂度是 O(n),集合的查询复杂度是 O(1),字典的查询复杂度也是 O(1)。关于这三种数据结构的各种操作的时间复杂度可参考链接: https://wiki.python.org/moin/TimeComplexity , 这里是中译版本 http://www.orangecube.net/python-time-complexity

看到这道题,你可能一眼就能想到的解决办法就是暴力破解法。大概思路就是 n*n 轮遍历,第1个n轮是首先取出第一个元素 n ,然后从剩下的元素中遍历,找到某个等于 target-n 的值,如果没找到,就开始第2个n轮遍历,取出第二个元素,直到找到目标元素为止。

def two_sum(nums, target):
   for i, n in enumerate(nums):
       if target - n in nums[i + 1:]:
           return n, target - n

nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target))

>>>(2, 7)

使用 in 关键字在列表中查找元素的时间复杂度是O(n),外层for循环的复杂度也是O(n),所以这种算法的时间复杂度是 O(n^2)

然后我发现另外一个缺点,在 Python 中,没法基于原数组进行遍历,外循环每次迭代的时候,要创建一个新的列表nums[i + 1:],这样就造成了这个算法的空间复杂度变成了 O(n),如果换成C或者Java就不会有这个问题,这也是 Python 慢的一种原因吧。

方法二

既然列表查询的复杂度是 O(n),而 集合和字典的查询复杂度是常量 O(1),所以我们可以考虑先将列表转换成字典或者集合。

def two_sum(nums, target):
   s= set(nums)
   for n in nums:
       m = target - n
       if m in s and n != m:
           return n, m

nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target))

最终这个算法的复杂度就变成了 O(n),空间复杂度也是 O(n),所以这种算法要优于第一种的。如果将列表转换为字典,可以将列表元素作为字典的key,而元素的索引位置作为字典的value,这样就可以知道这两个目标元素的位置是哪里,这是用集合没法做到的。

总结

学算法首先要把基本的数据结构搞懂,例如列表、集合、字典、队列、链表、树、二叉树、图等等,理解各种数据结构操作的特性,然后你做起题目来就游刃有余了。


推荐阅读





优秀如你
用转发点赞支持我

以上是关于来刷 LeetCode 啊的主要内容,如果未能解决你的问题,请参考以下文章

用 C 语言来刷 LeetCode,网友直呼:那是真的牛批...

用 C 语言来刷 LeetCode,网友直呼:那是真的牛批...

LeetCode按照怎样的顺序来刷题比较好?

初刷LeetCode的感受

LeetCode 329. 矩阵中的最长递增路径

Leetcode 计划