热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据结构杂谈番外篇——时间复杂度计算

我们先给出推导的方法,然后下面一步一步来推导。推导大O阶用常数1取代运行时间中的所有加法常数在修改后的运行次数函数中,只保留最高阶项如果最高阶存在且

我们先给出推导的方法,然后下面一步一步来推导。

推导大O阶


  1. 用常数1取代运行时间中的所有加法常数
  2. 在修改后的运行次数函数中,只保留最高阶项
  3. 如果最高阶存在且不是1,则去除这个项相乘的常数
  4. 所得结果即为大O阶

示例

int sum = 0,n = 100; //以分号结尾,代码执行一次
sum = (1+n)*n/2 //执行一次
cont<

运行次数为3&#xff0c;而在上面推导的推导大O阶方法中我们说了&#xff0c;用1代码所有的加法&#xff0c;什么意思呢&#xff1f;我们的3是经过1&#43;1&#43;1算出来的&#xff0c;我们用1代替所有的加法。而这个表达式只有1&#xff0c;没有最高阶项&#xff0c;所以结果1即为大O阶。我们把具有O&#xff08;1&#xff09;的时间复杂度的叫做常数阶

int i;
for(i &#61; 0;i{/*其他常数阶程序代码*/
}

我们可以发现&#xff0c;花括号里的就是常数阶&#xff0c;而for循环循环了n次&#xff0c;也就是说&#xff0c;做了n&#43;常数阶次执行次数&#xff0c;根据上面推导大O阶方法&#xff0c;我们找到了最高阶项n&#xff0c;舍弃后面常数项&#xff0c;所以我们的时间复杂度为O(n)&#xff0c;我们把这类情况称为线性阶

顺便一提&#xff0c;一般来说&#xff0c;我们分析算法的时间复杂度&#xff0c;关键就是分析循环结构的运行情况

int count &#61; 1;
while(count {count &#61; count * 2;/*其他常数阶程序代码*/
}

从这里的代码我们可以看出&#xff0c;退出循环的条件是count2x&#61;n2^{x}&#61;n2x&#61;n的式子&#xff0c;而我们大O(n)里面的n实际上指的是这里的x&#xff0c;根据高中数学所学的指对互换&#xff0c;我们可以写出x&#61;log2nx &#61; log_2nx&#61;log2n。所以这个循环的时间复杂度为O(logn)&#xff0c;我们把这类情况叫做对数阶

int i ,j ;
for (i - 0; i }

对于这种就不必多说了&#xff0c;时间复杂度为O(n2)(n^2)(n2)。我们把这类情况叫做平方阶

说完上面所有的情况了&#xff0c;现在我们来几个题来练手。

x &#61; 0;y &#61; 0;
for(int k &#61; 0;k}
for(int i &#61; 0;i}

分析算法&#xff0c;根据推导大O阶方法&#xff0c;第一行执行1次&#xff0c;第一个循环执行n次&#xff0c;第一个内嵌循环外层n次&#xff0c;内层n次&#xff0c;也就是n的平方。把常数变为1&#xff0c;然后抓大头&#xff0c;最高项系数为1&#xff0c;那么只剩下n2n^2n2。所以该代码的时间复杂度为O(n2)(n^2)(n2)&#xff0c;从完整的代码分析下来我们也可以发现&#xff0c;实际上我们只需要找最复杂的那个循环开始分析就可以了&#xff0c;因为其他的代码所含的时间复杂度最终根据推导大O阶方法都会被省略。下面看一个比较难的例子。

void exam(fload x[][],int m,int n)
{float sum[];for(int i &#61; 0;i}

最复杂的就是中间的内嵌循环&#xff0c;外层循环为从0到m&#xff0c;内层循环0到n&#xff0c;所以该时间复杂度应为O(m&#43;n)。

for(i &#61; 1;i<&#61;n;i&#43;&#43;)for(j &#61; 1;j<&#61;n;j&#43;&#43;){c[i][j]&#61;0;for(k &#61; 1;k<&#61;n;k&#43;&#43;)c[i][j] &#61; c[i][j]&#43;a[i][k]*b[k][j];}

上面这个是一个N×N矩阵相乘的算法&#xff0c;连续三层循环&#xff0c;第一次执行次数为n&#xff0c;第二层执行次数也为n&#xff0c;第三层执行次数还是n。所以该题算法复杂度为O(n3)(n^3)(n3)

for(i &#61; 1;i<&#61;n;i&#43;&#43;)for(j&#61;1;j<&#61;i;j&#43;&#43;)for(k&#61;1;k<&#61;j;k&#43;&#43;)x &#61; x&#43;1&#xff1b;

这里最外层执行次数n&#xff0c;但是最外层执行1次&#xff0c;第二层就循环1次&#xff1b;最外层执行第2次&#xff0c;第二层循环两次&#xff1b;根据等差数列求和公式&#xff0c;即第二层有1&#43;2&#43;3&#43;…&#43;n&#xff0c;即n(1&#43;n)2\frac{n(1&#43;n)}{2}2n(1&#43;n)次。当然第三层就不好理解了&#xff0c;所以我们接下来换一种方法。

对于三层循环问题&#xff0c;我们还是直接列出最外层的前几项比较好。在i &#61; 1的时候&#xff0c;内层循环全部加起来只循环一次。在i &#61; 2的时候&#xff0c;第二层循环启动两次循环&#xff0c;所以总共执行1&#43;2&#xff0c;对于i &#61; 3&#xff0c;第二层启动三次循环&#xff0c;第三层也是三次循环。也就是说总共执行1&#43;2&#43;3。如果听不太懂&#xff0c;我们可以用图来表示&#xff0c;即&#xff1a;

image-20220112191100363

所以实际上以上规律是由n来控制的&#xff0c;从上面的图来看的话&#xff0c;根据我们所得规律&#xff0c;i&#61;1里面有一个i(1&#43;i)2\frac{i(1&#43;i)}{2}2i(1&#43;i)&#xff0c;i &#61; 2里面也有一个i(1&#43;i)2\frac{i(1&#43;i)}{2}2i(1&#43;i)&#xff0c;以此类推我们可以写出下面的式子&#xff1a;∑i&#61;1ni(i&#43;1)2\sum^n_{i&#61;1}\frac{i(i&#43;1)}{2}i&#61;1n2i(i&#43;1)

我们化简一下上面的式子&#xff1a;∑i&#61;1n(i22&#43;i2)&#61;12∑i&#61;1n(i2−i)\sum^n_{i&#61;1}(\frac{i^2}{2}&#43;\frac{i}{2}) &#61; \frac1 2\sum^n_{i&#61;1}(i^2-i)i&#61;1n(2i2&#43;2i)&#61;21i&#61;1n(i2i)

这里用等差求和公式带入求解&#xff0c;即可得出答案n(n&#43;1)(n&#43;2)6\frac{n(n&#43;1)(n&#43;2)}{6}6n(n&#43;1)(n&#43;2)&#xff0c;根据我们前面说的大O阶推导&#xff0c;可以得出本题的时间复杂度为n3n^3n3


推荐阅读
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 2020年第十一届蓝桥杯决赛JAVA B G题“皮亚诺曲线距离“的个人题解目录
    本文是2020年第十一届蓝桥杯决赛JAVA B G题“皮亚诺曲线距离“的个人题解目录。文章介绍了皮亚诺曲线的概念和特点,并提供了计算皮亚诺曲线上两点距离的方法。通过给定的两个点的坐标,可以计算出它们之间沿着皮亚诺曲线走的最短距离。本文还提供了个人题解的目录,供读者参考。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
author-avatar
民海育来仁湖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有