【从0到1学算法】大O表示法

一般我们在选择算法时,都是想要选择效率最高的算法。那算法的效率,用什么表示?没错!就是用大O表示法。

PS: 大O表示法中,log即为log2,后面不再说明。

下面以简单查找和二分查找,在含有n个元素的有序列表中查找其中一个元素为例,下表总结了我们发现的情况。

使用简单查找时,最多需要猜测次数与列表长度相同,这被称为线性时间,大O表示法为O(n)。

二分查找则不同,最多需要猜测次数为logn(n为列表长度),这被称为对数时间(log时间),大O表示法为O(logn)。

基本概念

大O表示法指出了算法的速度有多快。

可能你会好奇,它的单位是多少?秒?没有单位,它并非指的是时间,而是从增量的角度衡量。

列表中查找元素,简单查找、二分查找的增速如下图。

假若我们不知道增速,只知道查找100个元素时的查找时间,猜测10000个元素时的查找时间:

对于简单查找,100个元素时为100毫秒,简单推算出10000个元素为10秒;

对于二分查找,100个元素时为7毫秒,简单推算出10000个元素为700毫秒。

PS:简单推算 10000个元素时的运行时间= 运行时间(100个元素时)* 100

简单查找的推算是对的,因为的增速是n,而二分查找的推算是错的,它的增速为logn,这便不能理所当然简单推算了。

很显然,我们只要知道算法的增速,便能知道它在n个元素中运行的运行时间了,大O表示法就是用来表示算法增速的。

专业描述:大O表示法表示操作数的增速,指出了算法运行时间的增速。

常见的大O运行时间(从快到慢)

  • O(㏒n) ?对数时间 比如二分查找
  • O(n) ? 线性时间 比如简单查找
  • O(n*㏒n) ? 比如快速排序
  • O(n2) ? ? 比如选择排序
  • O(n!) ? ? 比如旅行者问题

大O表示法的不同维度

时间复杂度

上述的大O表示法都是用来表示时间复杂度,而且通常指的是最坏情况下的时间复杂度。

通常有以下3种时间复杂度:

以简单查找为例子,在n个元素的列表中查找目标元素

  • 最好情况时间复杂度:目标元素刚好在列表第一个位置,那么只需要一次就能找到,时间复杂度为O(1)。
  • 最坏情况时间复杂度:目标元素在列表最后一个位置或者不在列表中,那么得需要遍历完整个列表才能得出结果,时间复杂度为O(n)。
  • 平均情况时间复杂度:考虑目标元素在列表中任何位置的情况。

    下面简单分析下:目标元素如果在列表中,出现的位置有n种情况,加上不在列表中这一种情况,总共n+1种情况。每种情况下需要遍历的次数如下表:

    目标元素所在位置 遍历次
    第1个位置 1
    第2个位置 2
    第3个位 3
    第n个位置 n
    不在列表中 n

    平均遍历次数=各种情况遍历次数相加÷总的情况数

    各种情况遍历次数相加为((1+2+3...+n)+n),总的情况数(n+1)

    平均情况复杂度为:

    ((1+2+3...+n)+n)/(n+1)=n(n+3)\2(n+1)

? 大O表示法,会省略系数、低阶、常量,所以平均情况时间复杂度是O(n)

空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,反映的是一个趋势。

空间复杂度比较常用的有:O(1)、O(n)、O(n2),我们下面来看看:

空间复杂度 O(1)

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。

例子:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 O(1)。

空间复杂度 O(n)

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
  j = i;
  j++;
}

第一行new了一个长度为n的数组m,占用大小为n,后面虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即O(n)。

PS:O(n2)的异同,不再累述。

以下常见排序算法的复杂度分析,感受一下时间复杂度和空间复杂度。

参考:《算法图解》

https://blog.csdn.net/jsjwk/article/details/84315770

https://www.cnblogs.com/jonins/p/9956752.html



文章首发于公众号【KEN DO EVERTHING】
本公众号专注于java相关技术,但不限于java、mysql、python、面试技巧、生活感悟等。分享优质博文,技术干货,学习资源等优质内容。
欢迎关注,一起学习,共成长!

原文地址:https://www.cnblogs.com/KEN-DO-EVERTHING/p/12264591.html

时间: 2024-08-14 10:42:14

【从0到1学算法】大O表示法的相关文章

【从0到1学算法】选择排序

又到了算法时间,今天我们来学第二种算法---选择排序.这里有个表格,记录了乐队及其作品的播放次数,如下: 要将它们按播放次数从多到少排序,要怎么做呢?有一种方法是这样子的,遍历列表,找出播放次数最多的乐队,将这个乐队添加到一个新的列表中. 再次这样做,找出第二多的乐队. 循环上述做法,最终便可得到一个有序列表. 上述这种算法便是选择排序法,n次遍历列表选出最大/小进行排序.我们用代码来一遍呗.题目:对一个数组从小大排序 # 找到最小值的索引 def?find_smallest(arr): ? ?

排序算法大集锦_二路归并排序_2&3(分治思想)

第一段代码和合并排序差不多,用它来和第二段代码--二路归并排序作对比. 这一系列博客的特点就是--给出每趟排序的结果 本来想着好好写一下过程,弄个图片什么的,不过觉得网上的解析太多了,都比较好,所以这些博客就算是对自己的总结吧. #include <stdio.h> #include <limits.h> #include <malloc.h> void merge(int *m, int x, int y, int z) { int b1,b2,i,j,k; b1=y

0基础学算法 第二弹 排序

大家好啊,这是0算法基础学算法系列第二篇,上次我在第一弹里讲了关于流程图的内容,我寻思着,这次讲些什么好呢,于是我决定,教大家一个很基础的算法,那就是排序,排序有很多方法,如果你有更多方法请在评论区里留言哦. 排序在程序中特别实用,常用的有快速排序,桶排序,冒泡排序,插入排序等等,在这里我不建议使用冒泡排序或者插入排序,建议桶排序和快速排序,这两个排序非常实用,时间复杂度低,理解起来也很容易,首先,你先思考一下,怎么用程序进行排序,然后你再来看看你的思路合理不合理,最后试着用程序实现它,实现后你

百度大神喊你一起学算法啦

小讲知道,很多人童鞋都曾被算法折腾得华发早生, 酱样子哈,那为什么还要学算法昵?为神马? 1. 算法和数据结构是IT技术人员的基本功,非常重要.可以说,算法几乎决定着一个程序员最终能走多远! 3. 大数据.云计算越来越红火,不会点算法,玩不转高大上的玩意儿,永远被人鄙视!装不了逼,把不了妹,买不了房,娶不了白富美(P.S.此条为小讲自行添加,使用了夸张手法,请忽略) 或许你说,去你的算法,我就是混饭吃,大公司不是我的菜. 而小讲俺是这样的 各位同学好,这门课的主讲老师是前百度工程师李老师,点这里

1169: 零起点学算法76——绝对公正的裁判

1169: 零起点学算法76--绝对公正的裁判 Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: 510  Accepted: 336[Submit][Status][Web Board] Description 大家知道我们学校的OnlineJudge吗?,你知道他会告诉你什么呢? Compiling : 您提交的代码正在被编译.Running : 您的程序正在OJ上运行.Judging : OJ

1110: 零起点学算法17——比较2个数大小

1110: 零起点学算法17--比较2个数大小 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 3272  Accepted: 1639[Submit][Status][Web Board] Description 输入2个整数,按照从大到小输出 Input 2个整数n和m(多组测试数据) Output 按照从大到小输出,中间用空格隔开(每组测试数据一行) Sample Input 14 32 2

排序算法大汇总

排序算法大汇总 排序算法是最基本最常用的算法,也是各大上市公司经常会被问道的面试知识点之一,不同的排序算法在不同的场景或应用中会有不同的表现,我们需要对各种排序算法熟练才能将它应用到实际应用中,才能更好的发挥他们的优势,那么今天我们来对各种算法进行一个简单的总结和分析. 冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻的两个元素比较,交换也发生在这两个元素之间.所以,如果两个元素相等,我们不会无聊地把他们俩交换:如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相

算法大神之路----排序(冒泡排序法)

冒泡排序法 冒泡排序法又称为交换排序法,是由观察水中冒泡变化构思而成,气泡随着水深压力而改变.气泡在水底时,水压最大,气泡最小,而气泡慢慢浮上水面时,气泡所受压力最小,体积慢慢变大. 冒泡排序比较方式是从第一个元素开始,比较相邻的元素大小,如果大小顺序有误,则对调后进行下一个元素比较.直到所有元素满足关系为止. 冒泡排序法分析 冒泡排序法平均情况下,需要比较(n-1)/2次,时间复杂度为O(n2),最好的情况只需要扫描一次,不用操作,即作n-1次比较,时间复杂度为O(n). 由于冒泡排序为相邻两

1165: 零起点学算法72——首字母变大写

1165: 零起点学算法72--首字母变大写 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 705  Accepted: 439[Submit][Status][Web Board] Description 输入一个英文句子,将每个单词的第一个字母改成大写字母. Input 输入数据包含多个测试实例,每个测试实例是一个长度不超过100的英文句子,占一行. Output 请输出按照要求改写后的英文句