时间复杂度的计算技巧-算法模型中的时间复杂度如何计算,有哪些技巧呢

大家好,我是微学AI,今天给大家介绍一下时间复杂度的计算技巧-算法模型中的时间复杂度如何计算,有哪些技巧呢,算法的时间复杂度是评估算法性能和效率的一种方式,它表示算法需要执行多少次基本操作才能完成其任务,这个数量随着输入规模的增加而增加。
时间复杂度通常用大O符号表示,例如O(n)、O(n²)等。其中,n表示输入规模,也就是算法需要处理的数据的大小。
在这里插入图片描述

一、常见的时间复杂度有:

O(1):常数时间复杂度,表示算法的执行时间不随输入规模的增加而增加,例如数组的索引访问。
O(log n):对数时间复杂度,表示算法的执行时间随着输入规模的增加而增加,但增加速度很慢,例如二分查找。
O(n):线性时间复杂度,表示算法的执行时间随着输入规模的增加而线性增加,例如遍历数组。
O(n log n):线性对数时间复杂度,表示算法的执行时间随着输入规模的增加而略微超线性增加,例如快速排序。
O(n²):平方时间复杂度,表示算法的执行时间随着输入规模的增加而平方级别增加,例如冒泡排序。

对于同一问题,不同的算法可能具有不同的时间复杂度,因此在选择算法时需要综合考虑时间复杂度、空间复杂度以及算法的实现难度等因素。

二、在C语言中的算法时间复杂度

我们可以通过对程序执行的次数的统计来计算其时间复杂度。一般情况下,我们关注的是最坏情况下程序的执行次数,因为最坏情况下的时间复杂度往往是算法的瓶颈。

对于一个基本操作(如赋值、比较、运算等),我们假设其执行时间为常量单位时间(即 O(1) 时间复杂度)。那么我们可以根据程序的代码结构和控制流程,计算出程序在最坏情况下的执行次数,从而确定其时间复杂度。下面是一些常见的时间复杂度及其示例:

  1. O(1) 常数级别
int a = 1;
int b = 2;
int c = a + b;

上述代码中,三个赋值语句和一个加法运算都是 O(1) 操作,总的时间复杂度也是 O(1)。

  1. O(n) 线性级别
for (int i = 0; i < n; i++) {
    printf("%d ", i);
}

上述代码中,for 循环中的 printf 语句会被执行 n 次,因此总的时间复杂度是 O(n)。

  1. O(n^2) 平方级别
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        printf("%d ", i + j);
    }
}

上述代码中,内层循环中的 printf 语句会被执行 n^2 次,因此总的时间复杂度是 O(n^2)。

  1. O(log n) 对数级别
int i = n;
while (i > 0) {
    printf("%d ", i);
    i /= 2;
}

上述代码中,while 循环的条件是 i > 0,每次循环 i 会被除以 2,因此循环执行的次数为 log2(n)+1(以 2 为底的对数),因此总的时间复杂度是 O(log n)。

  1. O(n log n) 线性对数级别
for (int i = 0; i < n; i++) {
    int j = n;
    while (j > 0) {
        printf("%d ", i + j);
        j /= 2;
    }
}

上面代码中,外层循环会被执行 n 次,内层循环会被执行 log2(n)+1 次,因此总的时间复杂度是 O(n log n)。

计算时间复杂度时,一般采用大 O 记法,去掉常数项和低次项,只保留最高次项。另外,在计算时间复杂度时,需要注意以下几点:

  1. 循环嵌套时,内层循环次数的上界应该是外层循环的变量。
  2. 递归算法的时间复杂度需要进行递推处理,通常会使用主定理或递归树等方法。
  3. 位运算、矩阵乘法等特殊运算的时间复杂度需要特别处理。

三、递归算法的时间复杂度(python)

当涉及递归算法的时间复杂度时,有几种常见的复杂度级别。下面我将为你提供每种级别的例子代码:

  1. O(1) 常数级别的递归算法
def recursive_constant(n):
    if n <= 0:
        return
    print("Hello!")
    recursive_constant(n - 1)

上述代码中,无论输入是多少,函数都只会递归调用自身一次,因此时间复杂度为 O(1)。

  1. O(n) 线性级别的递归算法
def recursive_linear(n):
    if n <= 0:
        return
    print(n)
    recursive_linear(n - 1)

上述代码中,递归调用的次数与输入规模 n 成线性关系,因此时间复杂度为 O(n)。

  1. O(n^2) 平方级别的递归算法
def recursive_quadratic(n):
    if n <= 0:
        return
    for i in range(n):
        print(n)
    recursive_quadratic(n - 1)

上述代码中,递归调用的次数与输入规模 n 成平方关系,这个函数的时间复杂度是O(n^2),其中n表示输入的参数值。

我们来分析一下:

该函数是一个递归函数,每次递归调用都会执行一个for循环,循环次数为n。然后,递归调用将参数n减1,并再次执行相同的操作。

因此,在第一次递归调用中,for循环会执行n次。在第二次递归调用中,for循环会执行n-1次,以此类推,直到n减少到1为止。

总的执行次数可以近似为n + (n-1) + (n-2) + … + 1。根据等差数列求和公式,可以得到:

n + (n-1) + (n-2) + … + 1 = (n+1) * n / 2

因此,总的执行次数约为(n+1) * n / 2,也就是O(n^2)。

  1. O(2^n) 指数级别的递归算法
def recursive_exponential(n):
    if n <= 0:
        return
    print(n)
    recursive_exponential(n - 1)
    recursive_exponential(n - 1)

这个函数的时间复杂度是O(2^n),其中n表示输入的参数值。让我们来分析一下:

该函数是一个递归函数,每次递归调用都会执行两个递归调用。在每个递归调用中,参数n都会减1,并再次执行相同的操作。

因此,在第一次递归调用中,函数会执行一次print语句和两次递归调用。在第二次递归调用中,每次递归调用又会执行一次print语句和两次递归调用。以此类推,直到n减少到0为止。

总的执行次数可以近似为2^0 + 2^1 + 2^2 + … + 2^n。根据等比数列求和公式,可以得到:

2^0 + 2^1 + 2^2 + … + 2^n = 2^(n+1) - 1

因此,总的执行次数约为2^(n+1) - 1,也就是O(2^n)。

需要注意的是,递归函数的空间复杂度是O(n),因为每次递归调用都会在内存中创建新的函数调用栈。

四、 O(nlogn)与O(n^2logn)的时间复杂度:

1.O(nlogn)的例子

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    # 分割数组
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    
    # 合并并排序子数组
    return merge(left, right)

def merge(left, right):
    merged = []
    i, j = 0, 0
    
    # 依次比较两个子数组的元素,并按顺序合并
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            j += 1
    
    # 将剩余的元素添加到合并后的数组中
    merged.extend(left[i:])
    merged.extend(right[j:])
    
    return merged

arr = [4, 2, 7, 1, 5, 3]
sorted_arr = merge_sort(arr)
print(sorted_arr)

以上示例使用归并排序算法对一个数组进行排序,归并排序的时间复杂度为O(nlogn)。在每次递归中,数组会被分割成两半,每一层递归需要O(n)的时间复杂度来合并两个已排序的子数组。

  1. O(n^2logn)的例子:
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        
        # 在已排序的子数组中找到合适的位置插入元素
        while j >= 0 and arr[j] > key:
            arr[j+1] = arr[j]
            j -= 1
        
        arr[j+1] = key

def nested_insertion_sort(arr):
    for i in range(len(arr)):
        insertion_sort(arr)
    
    return arr

arr = [4, 2, 7, 1, 5, 3]
sorted_arr = nested_insertion_sort(arr)
print(sorted_arr)

以上使用嵌套的插入排序算法对一个数组进行排序,其中外层循环对数组进行n次插入排序,而插入排序的时间复杂度为O(n^2)。 因此,整个算法的时间复杂度为 O(n^2 logn)。每次插入排序都需要O(n^2)的时间复杂度,而总共需要进行logn次插入排序。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s-服务网格实战-入门Istio

istio-01.png 背景 终于进入大家都比较感兴趣的服务网格系列了&#xff0c;在前面已经讲解了&#xff1a; 如何部署应用到 kubernetes服务之间如何调用如何通过域名访问我们的服务如何使用 kubernetes 自带的配置 ConfigMap 基本上已经够我们开发一般规模的 web 应用了&#xf…

app逆向入门之车智赢

声明&#xff1a;本文仅限学习交流使用&#xff0c;禁止用于非法用途、商业活动等。否则后果自负。如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;本教程也没有专门针对某个网站而编写&#xff0c;单纯的技术研究 目录 案例分析技术依赖参数分析效果展示代码分享…

电压放大器可用于什么场合

电压放大器是电子器件中常见的一种放大器类型&#xff0c;它可以将输入信号的电压放大到更大的幅度&#xff0c;以满足特定应用的需求。电压放大器广泛应用于多个领域和场合&#xff0c;下面将详细介绍一些使用电压放大器的场景。 音频放大器&#xff1a;音频放大器是电压放大器…

Spark的主要概念

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容&#x1f34a; 1. RDD&#x1f34a; 2. Spark SQL&#x1f34a; 3. Spark Streaming&#x1f34a; 4. MLlib&#x1f34a; 5. GraphX&#x1f34a; 总结 &#x1f4e2;文章总结&#x1f4e5;博主目标 &#x1f50a;博主介绍…

linux——网络套接字编程

目录 一.简单了解TCP和UDP协议 二.网络字节序 三.socket常见的编程接口 1.介绍接口 2.sockaddr结构 四.简单的UDP网络程序 1.recvfrom和sendto 2.server.cc 3.client.cc 五.简单的TCP通信 1.client.cc 2.server.cc 一.简单了解TCP和UDP协议 此处我们先对TCP(Transm…

零日漏洞预防

零日漏洞&#xff0c;是软件应用程序或操作系统&#xff08;OS&#xff09;中的意外安全漏洞&#xff0c;负责修复该漏洞的一方或供应商不知道该漏洞&#xff0c;它们仍然未被披露和修补&#xff0c;为攻击者留下了漏洞&#xff0c;而公众仍然没有意识到风险。 零日攻击是如何…

AI“走深向实”,蚂蚁蚁盾在云栖大会发布实体产业「知识交互建模引擎」

数字化起步晚、数据分散稀疏、专业壁垒高、行业知识依赖「老师傅」&#xff0c;是很多传统产业智能化发展面临的难题。2023年云栖大会上&#xff0c;蚂蚁集团安全科技品牌蚁盾发布“知识交互建模引擎”&#xff0c;将实体产业知识与AI模型有机结合&#xff0c;助力企业最快10分…

uniapp subNvue 写的视频播放

文件下载地址 https://download.csdn.net/download/weixin_47517731/88500016https://download.csdn.net/download/weixin_47517731/88500016 1:在pages.json中配置视频播放页面 {/* 视频详情页面 */"path": "pages/detail-video/detail","style&q…

AD1255/AD1256硬件SPI开发实战与跳坑过程

AD1255/AD1256硬件SPI开发实战与跳坑过程 以上图片我们可以知道在t17阶段&#xff0c;数据是不能被读取的。另外最小是16个τCLKIN&#xff0c;具体是多少这个跟你配置的DATA_rate的设置有关系。 1.6 同步SYNC的时序 要同步SYNC&#xff0c;要么采用管脚SYNC&#xff0c;要么…

云原生环境下JAVA应用容器JVM内存如何配置?—— 筑梦之路

Docker环境下的JVM参数非定值配置 —— 筑梦之路_docker jvm设置-CSDN博客 之前简单地记录过一篇&#xff0c;这里在之前的基础上更加细化一下。 场景说明 使用Java开发且设置的JVM堆空间过小时&#xff0c;程序会出现系统内存不足OOM&#xff08;Out of Memory&#xff09;的…

词典查询工具django-mdict

什么是 django-mdict &#xff1f; django-mdict 不是词典软件&#xff0c;是词典查询的脚本工具&#xff0c;主要目的是解决词典数量多&#xff0c;手机容量不足的问题&#xff0c;是对其他词典软件局域网在线查询功能的补充&#xff0c;是用 django 实现的 mdict 词典查询工具…

微信小程序上传图片和上传视频的组件失效

微信小程序上传图片和上传视频的组件失效 今天公司的小程序展示图片和视频文字的页面上传图片组件突然失效&#xff0c;之前用的好好的&#xff0c;突然所有使用都都发现用不了&#xff0c;以为是代码出现问题&#xff0c;反复查了很久。换了一个openid居然就可以了&#xff0…

B端设计必看的9个开源组件库,值得收藏!

如果你想开发一款To B Web端产品&#xff0c;如何选择令人眼花缭乱的开源组件库&#xff1f;行业团队常用的B端开源组件库是什么&#xff1f;今天&#xff0c;我们将为您带来入门级开源组件库的介绍。你可以先有一个大致的了解&#xff0c;希望能对你有所帮助。未来&#xff0c…

MySQL 存储引擎

存储引擎&#xff1a;MySQL当中数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用的是不同的存储机制&#xff0c;索引技巧 锁定水平。以及最终提供的不同功能和能力&#xff0c;这写就是我们说的存储引擎。 功能&#xff1a; 1&#xff0c;mysql将数据存储在文…

接口自动化测试 —— 工具、请求与响应

一、工具&#xff1a; 1.工具介绍 postman &#xff1a;很主流的API测试工具&#xff0c;也是工作里面使用最广泛的研发工具。 JMeter&#xff1a; ApiPost&#xff1a; 2.安装postman&#xff1a; 安装好直接打开&#xff0c;不用注册。 二、通信模式&#xff1a; 1、…

【golang】Reflect反射整理、值修改、反射结构体、应用

Reflect 整理 反射是用程序检查其所拥有的结构&#xff0c;尤其是类型的一种能力&#xff1b;这是元编程的一种形式。反射可以在运行时检查类型和变量&#xff0c;例如&#xff1a;它的大小、它的方法以及它能“动态地”调用这些方法。这对于没有源代码的包尤其有用。这是一个强…

vite搭建vue3项目

npm init vite-app 项目名称 如果没安装vite就按照提示安装一下 运行 Done. Now run: cd smartWaterSystemnpm install (or yarn)npm run dev (or yarn dev)运行成功页面

Pytest-Allure及Allure命令使用

一、Allure介绍 Allure是Pytest用于生成测试报告的框架&#xff0c;提供丰富的测试报告功能&#xff1b; 二、Allure安装 Allure安装分为2块&#xff0c;分别是pytest-Allure库安装&#xff0c;本地生成报告并导出的命令行allure安装&#xff1b; 1、pytest-Allure库安装 …

适合女生的副业有哪些?整理了六个靠谱副业,女生必看

在这个互联网时代下&#xff0c;女生对于经济独立变得越来越看重。她们与男生一样&#xff0c;对于工作认真努力、追求进步&#xff0c;并且对于副业有着强烈的渴望和热爱。事实上&#xff0c;她们在副业领域的表现要远远超过很多男生&#xff0c;这一点不可否认。 女生在副业方…

客服管理者如何调动客服人员的积极性?

客户是企业的财富&#xff0c;良好的客户服务体验可以有效地促进企业的销售和声誉&#xff0c;因此&#xff0c;客服工作显得尤为重要。而客服人员的积极性直接影响了整个客服部门的质量和效率。如何调动客服人员的积极性&#xff0c;成为了每个客服管理者都需要面对的难题。本…