python 某个数是不是在某个范围内_非CS专业的Python学习指南(3)

点击蓝字关注我们

大家好,我是Ernest,一名在英国Amazon工作的软件开发攻(工)城(程)狮(师)?️。欢迎跟我继续学习Python!

17af17126437021b7c1cb425e3e80aed.png

此系列的前两篇文章 非CS专业的Python学习指南(1)和 非CS专业的Python学习指南(2)分别讲了 Python 火的原因和学习方法,以及 Python 语法基本功都需要学些什么。接下来的几篇文章我们就要进入到 Python 的算法部分。今天我们先来聊一聊什么是算法,以及如何通过复杂度分析来比较算法的优劣。

2865c55c252be774b5575cffae10b31f.png 今天我们先来聊一聊什么 是算法,以及如何通过复杂度分析来比较算法的优劣。 算法的定义 计算机科学对 算法(algorithm) 的定义是:

“一系列定义明确的具体计算步骤,可通用于解决一类问题。”

这个定义是不是有点天马星空?那我们先来看一个简单的例子:

大家小学学习多位数加法的时候,老师都是教大家从最低数位开始做单位数加法,必要时进行进位操作,然后一步步推进到更高的数位,直至完成整个多位数加法。

多位数加法其实就是一个很简单的算法:它明确地定义了一系列具体计算步骤(i.e. 从低数位到高数位的推进、每个数位的单位数加法、进位操作等),从而解决了多位数加法这一类的问题。这里需要明确一个概念: 算法是一种相对抽象的问题解决方法,即独立于你的实现方式。还是以上面的多位数加法为例:不论你是采用在草稿纸上徒手计算的方式,还是通过 Python/C++ 编程的方式,该运算方法的核心思想都是不变的。 Fun fact:LeetCode 有一道经典的算法题就是让你在只允许单位数加法和进位的前提下,如何实现多位数加法运算。链接在这里 https://leetcode.com/problems/add-two-numbers/  复杂度分析 现实生 活中,遇到的问题通常都会有多种解决方法。 我们会通过比较不同解决方法的 pros & cons ,来选用最有效的那一种来执行。 在算法的世界里也是一样的: 在解决同一个问题上,我们需要复杂度分析来比较不同算法的优劣,然后采用最有效的那一个 。 计算机科学对 复杂度分析(Complexity Analysis) 的定义是:

“用来分析某个算法所需消耗的计算资源的数量,可分为步骤数量(i.e.时间复杂度Time Complexity)和存储空间数量(i.e.空间复杂度Space Complexity)。”

一般来说,复杂度分析注重于一个算法在应对一个超大数据集时的最坏情况。为什么要重点考虑超大数据呢?因为我们使用计算机代替手动计算的目的,就是为了能够更高效地处理大量数据。为什么要重点考虑最坏的情况呢?因为最好的情况就是第一步就很幸运地找到了答案,这样的分析没有什么实际意义。而且超大数据集这个情况本身就代表了一种最坏情况,即数据大到超出手动计算的范围。

什么意思呢?我们来举一个简单的例子: 假设有一个长度为 N 的递增数列,我们想要寻找其中是否存在一个目标值。 我们当然可以使用最无脑的暴力搜索算法(Brute-Force Search),把这个数列从头到尾地扫一遍。如果长度 N 变得非常大,那么整个递增数列就变成了超大数据集。如果你要寻找的目标值在最后一步才找到,或者不存在于此数列中,那么最坏的情况就出现了:你需要扫完整个数列才能得出答案。所以,如果在 该问题 上运用暴力搜索算法的话,时间复杂度和数列长度 N 是线性关系,最坏的情况即进行 N 次比较。 但是我们可不可以巧妙运用问题陈述当中“递增数列”这个特性来找到更高效的算法呢? 回答是当然是可以的啦。 这种巧妙的算法叫做二分搜索算法(Binary Search):在每一次迭代中,你先通过 index 找到这个递增数列的中位数;如果中位数正好是目标值,那么完成搜索;如果目标值小于中位数 ,那么你可以丢掉中位数右侧的所有数值,把搜索范围缩小到中位数左侧;反之,如果目标值大于中位数,那么你可以丢掉中位数左侧的所有数值,把搜索范围缩小到中位数右侧;以此往复,不断缩小搜索范围,直至找到目标值,或搜索范围大小为0(i.e. 目标值不存在)。 c8b2f06819c6f32d2a62fc132dd589c1.gif 二分搜索 vs 暴力搜索 在二分搜索算法中,我们通过对搜索范围不断“对折”的方法,快速地缩小范围,最坏的情况是进行 log(N) 次对折(i.e. 进行 log(N) 次比较)。当数列长度 N 变得非常大(i.e. 超大数据集)时,二分搜索算法的 log(N) 次比较是远远小于暴力搜索算法的 N 次比较的,所以二分搜索算法更加高效。 题外话:既然都来拿举例子了,那递增数列的二分搜索算法自然肯定逃不了 LeetCode 经典题的地位的。 链接在这里 https://leetcode.com/problems/binary-search/ Big O Notation在前面比较暴力搜索算法和二分搜索算法的时候,我们讲到最坏的情况我们要分别进行 N 次比较和 log(N) 次比较。为了方便表达,我们可以用  Big O Notation 来表达一个算法的复杂度上限(upper bound)。例如,我们可以说长度为 N 的递增数列的二分搜索算法的时间复杂度为 O(log(N)),意为其时间复杂度一定小于等于log(N)。 在用 Big O Notation 表达算法的复杂度时,如果遇到遇到一个多项式函数,我们可以只保留最高项,并且省略最高项的系数。例如 f(N) = 3N + 20000log(N) + 1 ,当 N 变得无穷大时,20000log(N) + 1 的变化相比 3N 来说小得可以忽略不计。我们可以说 f(N) = O(N)。 关于 Big O Notation 中不同函数分类的大小比较,这里给大家一张表格,具体的数学原理就不深入展开啦。 bcb756cf607a7e9c7bbc53d1aefede37.png 常用的函数阶:N 变大时增长速度越慢的函数靠前 29e2fcac29ba3834d5e17372197b6959.gif

ErnestX

 July

30.2020

到这里,本期的Python小课堂就结束了。不知道你学会了吗?欢迎公众号留言反馈给我们。ErnestX老师也在我们的求职社群里,还想听点什么,关注我们的公众号并添加小烈爸爸微信,来社群听Ernest老师的更多精彩分享吧~

往期推荐

非CS专业的Python学习指南(1)

毕业才开始找工作的我是如何拿到RBS offer的(上)

【在英求职】毕业才开始找工作的我是如何拿到RBS offer的(下)

【在英工作】在VISA UK做程序员的一天

【在英求职】投行必备的财务基础——财务建模Financial Modeling

5609dffe7f6b43eaf919c60a34655909.png

UKCNSS,一个专注于英国求职,工作与交友,扩展与提高你人脉圈子的高品质网络社群

我知道你Wow在看

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值