复杂度

每个程序员都应该收藏的算法复杂度速查表

余生颓废 提交于 2020-04-07 05:34:05
算法复杂度这件事 这篇文章覆盖了计算机科学里面常见算法的时间和空间的大 O(Big-O)复杂度。我之前在参加面试前,经常需要花费很多时间从互联网上查找各种搜索和排序算法的优劣,以便我在面试时不会被问住。最近这几年,我面试了几家硅谷的初创企业和一些更大一些的公司,如 Yahoo、eBay、LinkedIn 和 Google,每次我都需要准备这个,我就在问自己,“为什么没有人创建一个漂亮的大 O 速查表呢?”所以,为了节省大家的时间,我就创建了这个,希望你喜欢! — Eric 图例 绝佳 不错 一般 不佳 糟糕 数据结构操作 数据结构 时间复杂度 空间复杂度 平均 最差 最差 访问 搜索 插入 删除 访问 搜索 插入 删除 Array O(1) O(n) O(n) O(n) O(1) O(n) O(n) O(n) O(n) Stack O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n) Singly-Linked List O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n) Doubly-Linked List O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n) Skip List O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n) O

程序复杂度之圈复杂度

南楼画角 提交于 2020-04-06 08:34:15
圈复杂度(Cyclomatic complexity)也称为条件复杂度或循环复杂度,是一种软件度量,是由Thomas J. McCabe, Sr. 在 1976 年提出,用来表示程序的复杂度,其符号为 VG 或是 M。圈复杂度是对源代码中线性独立路径数的定量测量。 圈复杂度使用的程序的控制流图来计算:在图中的节点对应于程序中一组不可分割的命令[代码行],有向边连接两个可连续执行的节点;[可连续执行的两个节点:第二个节点的命令组可能在第一个节点执行后立刻开始执行]。圈复杂度可以应用到独立的功能,模块,方法或类。 基础路径测试:通过测试用例测试程序中的每个线性无关的独立路径;在这种测试策略下,测试用例的数目将等于该程序的圈复杂度; 圈复杂度定义 圈复杂度度量的是程序中线性独立路径的数量;例如:如果程序中不包含控制、判断、条件语句(例如 if,swith 等),那么复杂度就是 1 ;因为整个程序只有一条执行路径;如果程序包含一条IF语句,那么就会有两条路径来执行完整个程序(IF为 TRUE,IF 为 FALSE),所以这时候的复杂度就是 2;两个嵌套的 IF 语句,或者包含两个判断条件的一个 IF 语句,复杂度就是 4; 在数学上,一个结构化程序的圈复杂度通过该程序的控制流图来定义;控制流图包含程序的基本块(图的节点),和两个基本块之间可执行性(图的边)。 原理: 上图:单程序的控制流图

BZOJ3277 串(后缀自动机)

試著忘記壹切 提交于 2020-04-06 00:27:08
  对多串建立SAM的一种方法是加分隔符。于是加完分隔符建出SAM。   考虑统计出每个节点被多少个串包含。让每个串各自在SAM上跑,跑到一个节点就标记(显然一定会完全匹配该节点,因为是对包含其的串建的SAM)并暴跳fail,遇到已经被该串标记过的点就停止。   这样暴力的复杂度容易感性证明是O(Lsqrt(L))(L即所有串总长度),因为暴力一个串的过程中,SAM每个点至多被标记一次,每一步跳fail的次数也显然不会超过该串长度,于是对该串的复杂度是min(L,|S| 2 )(S即该串长度),总的最劣复杂度大约就是sqrt(L)个长度为sqrt(L)的串时取得,且常数极小。当然也可以使用树剖实现,不用分析复杂度就能知道是O(Llog 2 L)。   然后递推求出每个点被经过时的具体贡献,也即其到parent树的根的路径上所有出现在至少k个串中的点的len-lenfa值的和。再对每个串各自跑一遍累加所经过点的贡献即可。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define ll long long #define N 400010

空间复杂度

馋奶兔 提交于 2020-04-04 13:14:59
其实,空间复杂度比时间复杂度相对来说容易分析得多。 下面这段代码中,只有第三行申请的空间为 n ,其他代码申请的空间都是常数阶。因此这段代码的空间复杂度为 O(n)。 其实,我们常见的空间复杂度主要有O(1)、O(n)、O(n2 )。 像O(logn)、O(nlogn)这样的对数阶复杂度平时基本遇不到。 void print(int n) { int i = 0; int[] a = new int[n]; for (i; i <n; ++i) { a[i] = i * i; } } 欢迎关注个人公众号,可直接扫描以下二维码或微信搜索“阿毛聊技术”。 来源: https://www.cnblogs.com/limaodeng/p/12631210.html

一些面试题,转关注的一个博客

一个人想着一个人 提交于 2020-03-29 12:13:37
腾讯面试题: tcp 三次握手的过程, accept 发生在三次握手哪个阶段? 答accept发生在三次握手之后。 第一次握手:客户端发送syn包(syn=j)到服务器。 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。 三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。 const 的含义及实现机制,比如: const int i, 是怎么做到 i 只可读的? const用来说明所定义的变量是只读的。 这些在编译期间完成,编译器可能使用常数直接替换掉对此变量的引用。 用 UDP 协议通讯时怎样得知目标机是否获得了数据包 可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int。 发送方在发送数据时将此ID和发送时间记录在本地。 接收方在收到数据后将ID再发给发送方作为回应。 发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。 求一个论坛的在线人数,假设有一个论坛,其注册 ID 有两亿个,每个 ID 从登陆到退出会向一个日志文件中记下登陆时间和退出时间

敏捷开发中的故事点到底是什么?如何预估故事点?

时光毁灭记忆、已成空白 提交于 2020-03-25 16:47:22
3 月,跳不动了?>>> 故事点 是敏捷项目管理和开发中的一种抽象的度量单位,用于估计实现一个或多个用户故事的复杂度,它是对工作量的一种描述方式。一个故事点就是一个数字,透过这个数字告诉整个团队用户故事的复杂度。复杂度包括功能的难易程度、风险和花多大的功夫。 故事点(story point)和预估时间(estimated)不一样,故事点是一种相对的估计,它并不能和类似“人/天”这样的单位画等号,因为每个人完成同样复杂度的工作所需的时间是不同的。我们举个例子说明一下: 假设T团队有A、B、C三位员工,A君的能力是B君的2倍,B君的能力是C君的2倍(能力是不能这样对比的,这里只是方便说明问题),T团队约定10天为一个迭代,现在他们想计划一下未来的工作。如果按照预估时间的方式,一个用户故事B君觉得需要1天,A君觉得0.5天就可以,C君觉得需要2天,那么他们最终定多少呢? 这里可能出现两种结果: 第一种结果,A君说这个我来做,写0.5天吧!如果按照这个方式,那么整个计划会议就演变成分工会议,A君挑若干的用户故事,自己进行估时,B君和C君也是如此,当每个人的总估时都逼近10天的时候,那么这个迭代的目标就确定了。这是很多团队实际采用的方式,看起来好像没问题,但是久而久之,这种方式的弊端就会显现出来。 自己干自己的,不关心全局的进展。既然每个人自己的工作内容都已经确定

数据结构&算法

纵然是瞬间 提交于 2020-03-23 20:35:35
3 月,跳不动了?>>> 在分析算法效率时,经常关注以下两种复杂度: (1)最坏情况复杂度:T worst (n) (2)平均复杂度:T avg (n) 易知T avg (n)<=T worst (n) 注:一般分析最坏情况复杂度,因为平均复杂度不容易找 下表能够比较直观的看出各个复杂度的运行时间 1 2 4 8 16 32 C(常函数) 1 1 1 1 1 1 logn 0 1 2 3 4 5 n 1 2 4 8 16 32 nlogn 0 2 8 24 64 160 n 2 1 4 16 64 256 1024 n 3 1 8 64 512 4096 32768 2 n 2 4 16 256 65536 4294967296 n! 1 2 24 40326 2092278988000 26313×10 33 所以一般情况下避免出现后两种复杂度 下图是几种复杂度的增长速度 (图片来自慕课,陈越姥姥那堂课) 复杂度分析的窍门: 若已知T 1 (n) = O(f 1 (n))和T 2 (n) = O(f 2 (n)),则 T 1 (n) + T 2 (n) = max(O(f 1 (n)),O(f 2 (n))) (就是O(f 1 (n))和O(f 2 (n))的最大值) T 1 (n) × T 2 (n) = O(f 1 (n) × f 2 (n)) for循环的T(n) =

OO Project1 亿点感悟

a 夏天 提交于 2020-03-21 09:27:56
一、基于度量分析自己的程序结构 (1)Project1.1   毕竟是第一次的作业,总的来说挺简单的,类图也看上去一目了然,甚至我还有心思判断数据是不是可以用int而不是Bigintenger,从而节省空间,从后面的内容看来,这没必要。   接下来是类表和方法表,与后面的相比,写起来比较自由,没有很多面向对象的思想,多项式类中有一个项类的容器,并且承担了大部分工作,包括生成对象,求导,字符串化等,故复杂度较高,改进时应对多项式类尝试“减负”。 (2)Project1.2   这次的类图相比上次就略显复杂了,但主要增加的是类中的属性(两个三角函数)和方法,本次各类分工明确,结构明晰,难度个人认为较为简单。   下面是类表和方法表,可以看到,红色部分发生在解析输入、化简、字符化等处,个人认为除非将一个化简操作分为几个方法进行,否则,在解析时,结构化程度不佳,字符化时,循环复杂度也将居高不下。然后就是1.1的遗留问题,多项式类承担的任务仍然较多,这是因为除了其他类的生成,字符化等操作,还多出了求导操作以及求导后合并的操作。 (3)Project1.3   本次作业个人认为较难,而且和前两次相比难度是质的飞跃。前两次判断格式、解析输入都可以用正则表达式只手遮天,但这次由于因子嵌套,无论如何绕不开递归,而递归相比一般的循环、判断来说,难度不是一个级别。再加上对如此复杂的式子进行求导操作

OO第一单元总结

自作多情 提交于 2020-03-21 05:57:20
1 基于度量来分析自己的程序结构 第一次作业: uml类图: 其中main函数在Expression类中,Amalgamate类解析输入的格式,Expression类中为计算和合并。 Polynomial类为多项式类,该类将输入数据实例化为一个个多项式对象,该类的变量有系数,常数以及两个判定是否为系数和是否被Expression类中compute方法计算的boolean类型变量。 度量分析: 由此可以看出Expression.out的圈复杂度和模块设计复杂度较高,软件模块设计复杂度高意味模块耦合度高,这将导致模块难于隔离、维护和复用,圈复杂度大说明程序代码可能质量低且难于测试和维护,经验表明,程序的可能错误和高的圈复杂度有着很大关系。所以此部分还可以做出优化。 第二次作业: UML类图: FormatCheck类为字符串格式检查,Exp类记录的是多项式类型,并提供了一系列接口,Term类实现的则是整个多项式的合并方法,Polynomial类为多项式类,该类实现了对多项式的求导。 度量分析: 由此可以看出Polynomial.Polynomial方法的圈复杂度和模块设计度比较高,也是因为这部分是多项式求导的计算部分,所以复杂度较高。 第三次作业: UML类图: 第三次作业比较复杂,三个包加一个main函数类,compute包主要是多项式求导计算,包括DiffExpression类

数据结构&算法

好久不见. 提交于 2020-03-20 22:58:23
3 月,跳不动了?>>> 在分析算法效率时,经常关注以下两种复杂度: (1)最坏情况复杂度:T worst (n) (2)平均复杂度:T avg (n) 易知T avg (n)<=T worst (n) 注:一般分析最坏情况复杂度,因为平均复杂度不容易找 下表能够比较直观的看出各个复杂度的运行时间 1 2 4 8 16 32 C(常函数) 1 1 1 1 1 1 logn 0 1 2 3 4 5 n 1 2 4 8 16 32 nlogn 0 2 8 24 64 160 n 2 1 4 16 64 256 1024 n 3 1 8 64 512 4096 32768 2 n 2 4 16 256 65536 4294967296 n! 1 2 24 40326 2092278988000 26313×10 33 所以一般情况下避免出现后两种复杂度 下图是几种复杂度的增长速度 (图片来自慕课,陈越姥姥那堂课) 复杂度分析的窍门: 若已知T 1 (n) = O(f 1 (n))和T 2 (n) = O(f 2 (n)),则 T 1 (n) + T 2 (n) = max(O(f 1 (n)),O(f 2 (n))) (就是O(f 1 (n))和O(f 2 (n))的最大值) T 1 (n) × T 2 (n) = O(f 1 (n) × f 2 (n)) for循环的T(n) =