一个小故事带你了解大O表示法

 ☀前言:我们再编写程序时,不同的人有不同的思路,算法。那么如果需要比较谁的代码更好,使用哪种算法效率更高,我们一般会从代码程序的速率和所占空间去考虑。这时我们就需要使用一种方法描述程序运行的时间复杂度(运行快慢),空间复杂度(运行程序所占用的内存空间)

目录

引入案例

分析时间,空间复杂度

我们再次推广

以下是大O表示法常见的复杂度表示


引入案例

假如你和你的朋友再玩猜数字游戏,游戏规则如下

你的朋友在数字1到100中选出一个数字,那么你在不知情的情况下去猜这个数字是多少,你的朋友根据你猜的数字给出提示,指出你猜的数字是大了还是小了,不限猜的次数。

✏ 这是一个简单的游戏,最终你都可以猜到答案,但是那要怎么猜呢?

如果你从1开始逐个往上猜

‍♂️你:1

‍♂️朋友:小了

‍♂️你:2

‍♂️朋友:小了

......

‍♂️你:68

朋友:猜对了

这是什么查找方法呢?

说不好听的就是傻找,说得好听一些就是遍历

对于这种傻找,最理想的情况是你朋友选了1,你也正好从1开始,最糟糕的情况就是你朋友选了100,你还从1开始逐个往后猜,那傻子才玩这种游戏。

一个小故事带你了解大O表示法_第1张图片

✏ 那么有没有更好的办法快速猜到这个数字 ?

当然有,就是我们常说的二分法,根据二分法,我们可以这么猜

假如你朋友选了69

‍♂️你:50(1到100的中间数字)

‍♂️朋友:小了

‍♂️你:75(50到100的中间数字)

‍♂️朋友:大了

‍♂️你:63(75到100的中间数字)

‍♂️朋友:小了

‍♂️你:69(63到75的中间数字)

朋友:猜对了

使用二分法糟糕的情况是需要猜log2^n次,因为每次我们都是猜中间的数字,如果猜错了也没事,猜错了我们也可以排除一半的情况,n = 100,那么我们最多需要猜7次。比傻找最糟糕的情况少猜了93次。

分析时间,空间复杂度

对于上述的案例,我们如何表示傻找和二分法的时间复杂度,和空间复杂度呢?

写出代码程序然后运行计算得出结果需要多少秒,占用多少m内存?,当然不是。

我们使用大O表示法表示程序的空间复杂度和时间复杂度

写作:O(x),x表示时间或空间复杂度也称操作数

值得注意的是,分析程序,算法的复杂度是我们考虑的都是最糟糕情况下的复杂度

对于案例

傻找的最糟糕情况为猜100次

那么傻找的时间复杂度为O(100)= O(1)

我们假设记录每次猜的数字,最糟糕情况为猜100次也就需要记录100个数字

那么空间复杂度为O(100)= O(1)

---------------------------------------------------------

二分法的最糟糕情况为猜7次

那么二分法的时间复杂度为O(7)= O(1)

我们假设记录每次猜的数字,最糟糕情况为猜77次也就需要记录7个数字

那么空间复杂度为O(7)= O(1)

为什么O(100)= O(7)= O(1)?

因为在daO()表示法中,我们把所有的O(常数)均表示为O(1)

现在我们推广案例,假如从1到n猜数字。(一般情况下n很大)

那么

傻找的时间复杂度为O(n)

空间复杂度为O(n)

--------------------------------------------

二分法

的时间复杂度为O(log2^n

空间复杂度为O(n)

⭐我们再次推广

假设你和朋友玩猜数字先在1到n猜,然后朋友决定加大难度再从1到2n中选一个数字再猜一次,同样记录你每次猜的数字,不限猜的次数。

那么对于两次游戏

傻找的最糟糕情况为:

第一次需要猜n次

第二次需要猜2n次

傻找的时间复杂度为O(3n)= O(n)

空间复杂度为O(3n)= O(n)

----------------------------------------------------

二分法查找的最糟糕情况为:

第一次需要猜log2^n

第二次需要猜\log 2^{2n}

时间复杂度为O(\log2^{3n})= O(log2^n 

空间复杂度为O(\log2^{3n})= O(log2^n

✨接着朋友想再次提高难度

假设你和朋友玩猜数字先在1到n猜,你猜对后朋友将正确数字分成n等份(可能变成小数)再选一个数字让你再猜一次,同样记录你每次猜的数字,但是猜对第一次后不在记录(n等分后的数字不再记录),不限猜的次数,但是这次朋友不会提醒你数字大了还是小了。

(说白了他就是不想玩了,让你单纯找着玩,猜数字变成了找数字)

那么对于两次猜数字

傻找的最糟糕情况为:

因为朋友不在提醒,所以你需要找出所有结果。

先遍历n个数字,再“猜”第1个数字的时候又将其分为n个数字,那你还要再“猜”n次。如此进行下去,那么最糟糕的结果需要寻找n*n = n^{2}次。

这时

傻找的时间复杂度为O(n^{2}

 因为但是猜对第一次后不在记录你猜的数字n等分后的数字不再记录),所以

空间复杂度为O(n)

对于二分法,因为朋友不会提醒你数字大了还是小了。

所以你无法使用二分法查找

以下是大O表示法常见的复杂度表示

O(n) 也叫线性时间 一般是一次简单查找
O(\log n) 对数时间 常见有二分法
O(n*\log n) 常见有快速排序等
O(n^{2}) 常见于两层的for循环
O(n!) 拥有非常慢的运行速度 常见数性结构的遍历

复杂度比较

一个小故事带你了解大O表示法_第2张图片

(^表示次方) 

这就是平时我们在不靠直觉情况下,计算程序复杂度,判断哪个程序更“好”的方法。

你可能感兴趣的:(学习总结,python,大O表示法,时间复杂度,空间复杂度)