一文带你弄懂【时间复杂度】

news2024/9/23 13:24:20

文章目录

  • 算法
  • 时间复杂度
    • 时间复杂度计算
    • 常见的时间复杂度
    • 时间复杂度的差异
  • 总结


算法

算法(Algorithm)是求解一个问题需要遵循的,被清楚指定的简单指令的集合。

一个算法的评价主要从时间复杂度和空间复杂度来考虑。而时间复杂度是一个函数,定性描述该算法的运行时间,通常用大O符号表示。

常见的时间复杂度有O(1),O(logn),O(n),O(n2),O(2n)…等。

下面就来讲讲时间复杂度是怎么推算出来的吧。

时间复杂度

在计算机科学中,时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。

时间复杂度计算

我们定义算法中的语句执行次数称为语句频度或时间频度为T(n)。即T(n)表示程序的执行次数 。

方法1执行多少次:

	public int method1(){
	    System.out.println("hello"); //执行1次
	    return 0;			//执行1次
	}

没错,它内部一共执行2次。

那么我们来看下面的方法2执行几次:

    public int method2(int n){
        for(int i = 0; i<n ; i++){
         //i = 0 执行1次,i<n 执行n+1次,i++执行n次
            System.out.println("hello"); //输出语句执行n次
        }
        return 1; //return 执行一次
    }

对,它一共执行了 3n+3 次。那么对于方法1就有 T(n) = 2;对于方法2就有 T(n) = 3n + 3。

实际的代码肯定比示例中的代码复杂得多,去统计代码的执行次数显然不可能,所以算法一般使用T(n)的渐进估算值来反映代码的执行速度。而这个估算值我们用”时间复杂度”来表示。

所以针对方法1和方法2,如何根据T(n)估算出时间复杂度:

  1. 对于 T(n) = 2 ,由于T(n)是一个常数,那么时间复杂度可以直接估算为 1 。所以T(n) = 2 的时间复杂度为 1。 用标准的时间复杂度函数表示就是 O(1)。
  2. 对于T(n) = 3n + 3 ,随着n值得不断增长,常数3相对于3n来说可以忽略不计。而系数一般也会估算成1。相当于去掉了系数和常数,则该时间复杂度为n。 用时间复杂度函数表示就是O(n)。
  3. 依次推广到如下多项式中: 对于T(n) = 3n^2 + 3n + 3. 随着n值得不断增大,多项式后面的项的增长就远没有n2的增长大,可以直接舍弃低阶项和常数项,则只保留n的次方数最大的那一项,所以它的时间复杂度就为O(n3)。

总结以上规律:

  • T(n)是常数:时间复杂度为O(1);
  • T(n)不是常数:时间复杂度为O(T(n)的最高次项并且去掉最高次项的系数)。

常见的时间复杂度

方法1的时间复杂度为 O(1):

    //时间复杂度为 O(1)
    public void m1(){
        System.out.println("A");
        System.out.println("B");
        ...
        System.out.println("L");
    }

方法2的时间复杂度为 O(n):

    //时间复杂度为 O(n)    
    public int method2(int n){
        for(int i = 0; i < n ; i++){
            System.out.println("a");
        }
        return 1;
    }

方法3 时间复杂度为 O(n^2):

    //时间复杂度为 O(n^2)
    public void method3(int n){
        for(int i = 0; i < n ; i++){
            for(int j = 0 ; j < i ; j ++){
                System.out.println("a");
            }
        }
    }

方法4的时间复杂度为O(logn):

    public void method4(int n){
        int i = 1;
		while(i<n)
		{
		    i = i * 2;
		}
    }

从上面代码可以看到,在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。我们试着求解一下,假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n
也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)

方法5的时间复杂度为O(nlogN) :

    public void method5(int n) {
        for (int m = 1; m < n; m++) {
            int i = 1;
            while (i < n) {
                i = i * 2;
            }
        }
    }

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)

一般常见的时间复杂度进行如下排序(由快到慢)。

timeComplexitiesOrder.jpg

再用曲线图看一下时间复杂度。

timeComplexitiesChart.jpg

从图中也可以看出,随着元素变多,指数、阶乘级别的增长是最快的。显而易见其执行效率最低。

时间复杂度的差异

我们来举个例子:

算法A的相对时间规模是T(n)= 100n,时间复杂度是O(n)

算法B的相对时间规模是T(n)= 5n2,时间复杂度是O(n2)

算法A运行在老旧电脑上,算法B运行在某台超级计算机上,运行速度是老旧电脑的100倍。

那么,随着输入规模 n 的增长,两种算法谁运行更快呢?

640?wx_fmt=png

从表格中可以看出,当n的值很小的时候,算法A的运行用时要远大于算法B;当n的值达到1000左右,算法A和算法B的运行时间已经接近;当n的值越来越大,达到十万、百万时,算法A的优势开始显现,算法B则越来越慢,差距越来越明显。

这就是不同时间复杂度带来的差距。

总结

学好算法,则必须要理解时间复杂度这个重要基石。通过以上的分析,相信大家对时间复杂度有了一定的了解,大家共同进步,加油。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty核心技术四--Netty概述

1. 原生NIO存在的问题 NIO 的类库和 API 繁杂&#xff0c;使用麻烦&#xff1a;需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。需要具备其他的额外技能&#xff1a;要熟悉 Java 多线程编程&#xff0c;因为NIO编程涉及到Reactor模式&#xff0c;…

从tomcat说起全面理解Java web开发原理

从tomcat说起全面理解Java web开发原理 简介&#xff1a;Java开发分为Java ME&#xff0c;Java SE&#xff0c;Java EE。回顾过去这些的开发工作基本上都是围绕着Java EE的&#xff0c;在开发经历中分别经历了Java EE开发框架从jsp servlet一路经历了ssh&#xff0c; ss…

存储笔记8 ipsan

Module Objectives IP SAN的组件 IP SAN的好处 描述SAN中的IP融合及其影响 描述的基本架构 –iSCSI –FCIP –FCoE 讨论IP SAN技术的市场驱动因素 列出IP SAN技术 列出iSCSI的组件和连接选项 描述iSCSI体系结构和拓扑结构 解释iSNS操作 描述FCIP的体系结构 IP SAN互联…

Springboot整合第三方登录

文章目录 Springboot整合第三方登录为什么采用第三方登录整合第三方登录创建应用导入依赖创建controller类 Springboot整合第三方登录 为什么采用第三方登录 ​ 采用第三方登录可以避免重新注册账号的繁琐&#xff0c;也不需要再为密码和昵称发愁&#xff0c;而第三方登录有一…

Linux命令——top相关之Load Average平均负载

Linux 平均负载 Load Average 详解_系统1f分钟负载_欧晨eli的博客-CSDN博客 一、什么是Load Average&#xff1f; 系统负载&#xff08;System Load&#xff09;是系统CPU繁忙程度的度量&#xff0c;即有多少进程在等待被CPU调度&#xff08;进程等待队列的长度&#xff09;。…

2-JVM运行流程

JVM 是 Java 运行的基础&#xff0c;也是实现一次编译到处执行的关键&#xff0c;那么 JVM 是如何执行的呢&#xff1f; 程序在执行之前先要把java源代码&#xff08;.java&#xff09;转换成字节码文件&#xff08;.class&#xff09;。JVM 首先需要通过一定的方式类加载器&a…

如何做好前端性能优化

前端推荐官网: http://luckycola.com.cn/ 前言: 前端性能优化一直是一个前端开发人员必须关注的经典话题,虽然现在随着技术的不断发展,网页容器(浏览器、webview)性能也越来越强大,但是网站应用的功能也不断丰富,体积不可避免的增加,当网络环境等因素不好时,仍然会存在白屏时…

【后端面经】MySQL主键、唯一索引、联合索引的区别和作用

【后端面经】MySQL主键、唯一索引、联合索引的区别和作用 0. 简介1. 主键2. 唯一索引3. 联合索引4. 索引对数据库操作的影响5. 其他索引5.1 普通索引5.2 全文索引5.3 前缀索引 6. 总结7. 参考资料 0. 简介 索引是一类特殊的文件&#xff0c;用来存储检索信息&#xff0c;使数据…

数值天气预报期末复习

数值天气预报期末复习 文章目录 数值天气预报期末复习&#xff08;零&#xff09;重点需要掌握知识点&#xff08;一&#xff09;什么是数值天气预报&#xff08;二&#xff09;数值模式的分类&#xff08;三&#xff09;各坐标系下的大气运动方程组3.1 局地直角坐标系3.2 球坐…

绩效跃升地图读书笔记20130618

绩效跃升地图&#xff0c;从5月份开始看&#xff0c;每天中午吃完饭休息的时候&#xff0c;坐在工位上&#xff0c;把看手机刷视频看八卦的时间&#xff0c;换成看书的时间&#xff0c;直到6月15日看完一本书。发现其实利用好碎片时间&#xff0c;还是可以读不少书的。 “绩效…

网络端口地址转换 NAPT 配置

你是某公司的网络管理员&#xff0c;公司办公网需要接入互联网&#xff0c;公司只向 ISP 申请了一条专线&#xff0c;该专线分配了一个公司 IP 地址&#xff0c;配置实现全公司的主机都能访问外网。 技术原理 NAT 将网络划分为内部网络和外部网络两部分&#xff0c;局域网主机…

Java集合详解

目录 友情提醒第一章、集合体系概述1.1&#xff09;集合是什么&#xff1f;与数组的区别在哪1.2&#xff09;集合体系与分类 第二章、集合体系中的Collection和List接口/Set接口2.0&#xff09;List接口/Set接口两者区别2.1&#xff09;Collection接口中的常用方法2.2&#xff…

【系统开发】尚硅谷 - 谷粒商城项目笔记(一):项目准备工作

文章目录 项目准备工作人人开源搭建后台管理系统数据库搭建前端项目搭建后端模块代码生成 项目准备工作 人人开源搭建后台管理系统 码云搜索人人开源 renren-fast-vue&#xff1a;前端 renren-generator&#xff1a;代码生成器 renren-fast&#xff1a;后台管理系统 用git…

系统设计蓝图:终极指南

系统设计蓝图&#xff1a;终极指南 设计开发一个健壮的、可扩展的、高效的系统可以是令人望而生畏. 但是&#xff0c;了解关键概念和组件可以使流程更易于管理。在这篇博文中&#xff0c;我们将探索基本的系统设计组件&#xff0c;例如 DNS、负载平衡、API 网关等&#xff0c;以…

python详解(7)——进阶(1):排序算法

目录 &#x1f3c6;一、前言 &#x1f3c6;二、什么是算法&#xff08;简单&#xff09; &#x1f6a9;1、算法 &#x1f6a9;2、排序算法 &#x1f3c6;三、冒泡排序&#xff08;中等&#xff09; &#x1f3c6;四、快速排序&#xff08;困难&#xff09; &#x1f3c6;五&…

Android Studio 提高SDK下载速度

我们在下载Android SDK的时候&#xff0c;经常会出现下载失败的情况&#xff0c; 报android sdk manager not installing components之类的错误。 要如何加快SDK的下载速度呢 ? 我们可以通过修改Host来实现 关闭Android Studio的代理 首先&#xff0c;我们要关闭Android Stu…

华为HCIA备考 易错题整理 PART1

1.IEEE802.1Q定义的 VLAN 帧格式中VLAN ID总共有多少bit 答&#xff1a;12 2.NAPT允许多个私有IP地址通过不同的端口号映射到同一个公有IP地址上&#xff0c;且不需要做任何关于端口号的配置。 3.IEEE802.1Q定义的VLAN帧总长度为多少字节&#xff1f; 答&#xff1a;4 4.关于…

10种实用的Prompt技巧图解

收集整理了prompt engineering的10种实用技巧&#xff0c;以图解的方式解释了它们的主要原理。 本文追求以极简风格逼近这些方法的第一性原理&#xff0c;把黑话翻译成人话&#xff0c;并使用图片范例进行说明。 同时也加入了一些自己的理解&#xff0c;如有出入欢迎指正。 一&…

掌握Python的X篇_3_Python的两种编程方式:交互式与脚本式

掌握Python的X篇_3_Python的两种编程方式&#xff1a;交互式与脚本式 1. 交互式编程2. 脚本式编程3. 其他补充3.1 python源码文件后缀的问题3.2 关于原生工县和开发工具的选择 Python有两种编程方式&#xff1a; 交互式编程:写一行python语句&#xff0c;马上运行一行&#xf…

15-1.创建与引用自定义组件

目录 1 创建自定义组件 2 引用自定义组件 2.1 局部引用 2.2 全局引用 3 自定义组件的样式 1 创建自定义组件 在项目根目录下创建components&#xff0c;然后在components中创建 自定义组件名称 的文件夹&#xff0c;然后再自定义组件名称的文件夹中点击 新建Compon…