各算法时间复杂度总结—持续更新
来源:互联网 发布:变声器男变女甜美软件 编辑:程序博客网 时间:2024/06/04 00:46
这篇文章写得不会太好,毕竟我只是个小白,写来仅供参考,自己理顺一下时间复杂度方面的一些东西,大家可以到一些大牛那看到更加严密的证明方法。
我越来越发现,学ACM,算法是学多了,但是发现却越来越做不出题目了,因为水题开始变少,数据量开始变大,如果不打好分析题目的基础的话,就算你看得懂题,却已经落后大牛们一个level了。
比如,给你100000个数字,求和,每个数字的范围是-10000到10000,看似很简单,但是1e6 * 1e4 = 1e10,一百亿,int型整数是无法储存这么大的数字的。所以要上long long。当然,你所有题目都用long long,该过得过,本来就过不了的就要用字符型什么的,好像也无可厚非。不过分析问题的数据才是关键,无脑用long long并不能代替这种能力。
时间复杂度其实要怎么分析的呢?时间复杂度是遵循一个原则的,就是按照数据最大的那个数去得出结论。我们做题通常都是看见:题目给出多种情况,T<=10。最后计算的时候直接将T=10带入。
时间复杂度其实也是见仁见智的,因为我们一般只找复杂度高的那一部分,比如平方级别,指数级别,这些都放心的话,线性级别的读入啊,遍历啊,都是可以忽略的。
现在要来说一说OJ服务器的运算量了。一般遇到的题目都是1S的,1S的话跑一百万的数据是绝对可以的,一千万的话一般都可以过,但是到了一亿,除非是超级简单的逻辑判断,否则基本过不了了。
我现在主攻图论最短路的题目,就先从图论的算法开始说说。
Dijkstra点对点最短路:
for(i=1;i<=n;i++) { min=MAX; for(j=1;j<=n;j++) { if(!mark[j] && dist[j]<min) { //取出不在mark里的最小的dist[i] min=dist[j]; pos=j;//标记 } } if(min==MAX)//已经不能通了 break; mark[pos]=1;//把K加进来 //做松弛操作 for(j=1;j<=n;j++) { if(!mark[j] && dist[j]>dist[pos]+map[pos][j]) //start->j or start->pos,pos->j { dist[j]=dist[pos]+map[pos][j];//这步跟prim算法有点不同 } } }
这个是一个模板,是这个算法最核心的部分,其中n代表有多少个点,所以复杂度是O(2*n²),其余线性的部分可以忽略不计。但是其实dijkstra是可以优化的,百度上也有说,使用斐波那契堆这些优化,但是本小白还不怎么看得懂堆得东西。
Bellman—Ford单源最短路算法(可带负权,但不能有负权环)
bool Bellman_Ford(){for(int i = 1; i <= nodenum; ++i) dis[i] = (i == original ? 0 : MAX);for(int i = 1; i <= nodenum - 1; ++i)for(int j = 1; j <= edgenum; ++j)if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) {dis[edge[j].v] = dis[edge[j].u] + edge[j].cost;pre[edge[j].v] = edge[j].u;}bool flag = 1; //判断是否含有负权回路for(int i = 1; i <= edgenum; ++i)if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost){flag = 0;break;}return flag;}
nodenum就是点的个数,edgenum就是边的个数,从上面这段代码可以明显看出,时间复杂度应该为O(VE+E),V为点的个数,E为边的个数。这种算法有个很严重的问题,就是冗余量太大,进入两个for循环那部分很多时候都是无法操作的。所以有了一种算法叫SPFA,用队列和一个数组标记来去掉那么多冗余的部分。
SPFA单源最短路算法(可带负权,不可有负环)
这种算法的话,复杂度理论上说是O(K*E)k是进队列的次数,E是边数,但是百度上也说了,这种算法在国际上是不被认可的,他最坏的情况依然会回到Bellman的复杂度。
不过我觉得还是要支持下得,毕竟是国人提出的一种算法,而且你说快排最快可以达到nlgn的复杂度,慢也可以慢到n²的复杂度,但也是要用的,毕竟大多数情况是优化成功的。
Floyd-Warshall全局最短路算法:
void floyd_warshall(int n){ int i,j,k; for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (mat[i][k] + mat[k][j] < mat[i][j]) mat[i][j] = mat[i][k] + mat[k][j]; }这个复杂度就很高了,n依然是代表有多少个点,时间复杂度高达O(n^3)。这样可以算算,当有1000个点的时候,运算量是1e9,也就是10亿,适用范围就很局限了。
- 各算法时间复杂度总结—持续更新
- 各排序算法时间复杂度和空间复杂度对比总结
- 算法时间复杂度和空间复杂度总结
- 排序算法时间复杂度总结
- 降低时间复杂度的几种方法【持续更新】
- 八大排序算法总结&时间复杂度&稳定性
- 查找,排序算法时间复杂度总结
- 数据结构和算法--时间复杂度学习总结
- 算法的时间复杂度和空间复杂度-总结
- 【算法的时间复杂度和空间复杂度-总结】
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- 算法的时间复杂度和空间复杂度-总结
- |Tyvj|二叉树|P1441 求二叉树的先序序列
- 代理模式
- JMeter学习(二)录制脚本
- linphone-LinphoneInfoMessageImpl文件对应的JNI层文件分析
- iOS使用第三方工具(RegexKitLite)实现正则表达式
- 各算法时间复杂度总结—持续更新
- sessionManager定义
- Apache ranger 简介、原理、安装部署
- 【杭电】[4857]逃生
- 顺序表应用3:元素位置互换之移位算法
- Yii2增删改查-查询 where参数详细介绍
- hdu1811 Rank of Tetris(拓扑加并查集)
- android之在activity中控制另一个activity的UI更新_如何在activity之间传递handler
- HBase+ZooKeeper配置