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

大家好,我是微学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:returnprint("Hello!")recursive_constant(n - 1)

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

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

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

  1. O(n^2) 平方级别的递归算法
def recursive_quadratic(n):if n <= 0:returnfor 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:returnprint(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) // 2left = 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 += 1else:merged.append(right[j])j += 1# 将剩余的元素添加到合并后的数组中merged.extend(left[i:])merged.extend(right[j:])return mergedarr = [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 -= 1arr[j+1] = keydef nested_insertion_sort(arr):for i in range(len(arr)):insertion_sort(arr)return arrarr = [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次插入排序。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LuaHttp库写的一个简单的爬虫

LuaHttp库是一个基于Lua语言的HTTP客户端库&#xff0c;可以用于爬取网站数据。与Python的Scrapy框架类似&#xff0c;LuaHttp库也可以实现网站数据的抓取&#xff0c;并且可以将抓取到的数据保存到数据库中。不过需要注意的是&#xff0c;LuaHttp库并不像Scrapy框架那样具有完…

【C++ 系列文章 -- 程序员考试 201811 下午场 C++ 专题 】

1.1 C 题目六 阅读下列说明和C代码&#xff0c;填写程序中的空&#xff08;1&#xff09; &#xff5e;&#xff08;5&#xff09;&#xff0c;将解答写入答题纸的对应栏内。 【说明】 以下C代码实现一个简单乐器系统&#xff0c;音乐类&#xff08;Music&#xff09;可以使用…

VMware——VMware17设置WindowServer2012R2环境静态IP及关闭防火墙

目录 一、VMware17设置WindowServer2012R2环境静态IP1.1、工具栏虚拟机的设置步骤1.2、工具栏编辑的设置步骤1.3、静态IP的设置步骤 二、VMware17关闭WindowServer2012R2环境防火墙 一、VMware17设置WindowServer2012R2环境静态IP 1.1、工具栏虚拟机的设置步骤 打开VMware虚拟…

【工具】【IDE】Qt Creator社区版

Qt Creator社区版下载地址&#xff1a;https://download.qt.io/archive/qt/ 参考&#xff1a;https://cloud.tencent.com/developer/article/2084698?areaSource102001.8&traceIduMchNghqp8gWPdFHvSOGg MAC安装并配置Qt&#xff08;超级简单版&#xff09; 1.安装brew&…

el-table 列分页

<template><div><el-table:data"tableData":key"tampTime"style"width: 100%"><el-table-columnprop"name"label"姓名"width"180"></el-table-column><el-table-columnprop&quo…

上传LaTeX版本的NeurIPS文章到arXiv总是Failed的解决方案

往arXiv上传NeurIPS模版文章时&#xff0c;一直出现两处报错&#xff0c;一处是下图中的图片错误&#xff1a; 但是&#xff0c;我怀疑是不是图片并排放置的minipage不可用&#xff0c;于是改成了正常的图片形式来测试&#xff1a; 仍然是相同的错误&#xff0c;于是我又尝试去…

人工智能基础_机器学习014_BGD批量梯度下降公式更新_进一步推导_SGD随机梯度下降和MBGD小批量梯度下降公式进一步推导---人工智能工作笔记0054

然后我们先来看BGD批量梯度下降,可以看到这里,其实这个公式来源于 梯度下降的公式对吧,其实就是对原始梯度下降公式求偏导以后的梯度下降公式,然后 使用所有样本进行梯度下降得来的,可以看到* 1/n 其实就是求了一个平均数对吧.所有样本的平均数. 然后我们看,我们这里* 1/n那么…

从 Java 到 Rust,Substrate 优秀学员亲述 Web3 入门之路

你知道如何从 0 到 1 转行 Web3&#xff0c;找到技术开发岗位的一席之地吗&#xff1f;从后端核心开发到 Web3 测试&#xff0c;Substrate 课程优秀学员的区块链探索之路有哪些心得体会&#xff1f;10 月 26 日晚 20:00&#xff0c;第二期 Block Space 成长路径系列主题 AMA 活…

美团面试:Redis 除了缓存还能做什么?可以做消息队列吗?

这是一道面试中常见的 Redis 基础面试题,主要考察求职者对于 Redis 应用场景的了解。 即使不准备面试也建议看看,实际开发中也能够用到。 内容概览: Redis 除了做缓存,还能做什么? 分布式锁:通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Re…

基于CMFB余弦调制滤波器组的频谱响应matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1、CMFB余弦调制滤波器组原理 4.2、CMFB调制过程 4.3、CMFB特点 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ......................…

【触想智能】4U触摸工控机具有哪些优势?

工控机也叫工控主机&#xff0c;和我们常见的普通电脑主机是一样的&#xff0c;都是由CPU、主板、内存、硬盘、电源以及机箱组成的。 工控机有很多分类&#xff0c;有无风扇工控机、嵌入式工控机、上架式工控机、4U触摸工控机等。上架式工控机在市场上是比较受欢迎的&#xff0…

【LeetCode】剑指 Offer Ⅱ 第8章:树(12道题) -- Java Version

题库链接&#xff1a;https://leetcode.cn/problem-list/e8X3pBZi/ 类型题目解决方案二叉树的深搜剑指 Offer II 047. 二叉树剪枝递归&#xff08;深搜&#xff09;&#xff1a;二叉树的后序遍历 &#xff08;⭐&#xff09;剑指 Offer II 048. 序列化和反序列化二叉树递归&…

【idea】生成banner.txt

Spring Boot banner在线生成工具&#xff0c;制作下载英文banner.txt&#xff0c;修改替换banner.txt文字实现自定义&#xff0c;个性化启动banner-bootschool.netSpring Boot banner工具实现在线生成banner&#xff0c;轻松修改替换实现自定义banner&#xff0c;让banner.txt文…

Vue项目创建与启动(2023超详细的图文教程)

目录 一、下载node.js 二、下载vue-cli与webpack插件 三、项目初始化(项目配置详细信息) 四、项目启动 五、Vue项目工程结构&#xff08;扩展知识&#xff09; 一、下载node.js 1.检测是否已经安装过node.js 打开控制台,输入 npm -v如果有会显示对应版本 如果没有会显示…

7个UI设计必备课程,小白必看!

无论你是想提高技能的资深UI设计师还是网站开发人员&#xff0c;又或者是刚转行不久的UI设计新手&#xff0c;学习UI设计课程都会让你做出更美观、更有影响力的UI界面设计作品。现在网上有很多网上的UI设计课程。通过这些课程&#xff0c;你可以自己学习、掌握一些UI设计的基础…

Oil Crop Science:DAP-seq技术揭示花生中AhTWRKY24和AhTWRKY106转录因子下游调控基因

2023年6月4日&#xff0c;青岛农业大学草业学院宋辉教授课题组的研究成果&#xff0c;发表在Oil Crop Science期刊上&#xff0c;文章题目为Identification of the target genes of AhTWRKY24 and AhTWRKY106 transcription factors reveals their regulatory network in Arach…

react中的useReducer复杂的状态管理

一、useReducer reducer官网教程 useReducer 是 React 提供的一个用于状态管理的 Hook。它可以替代 useState&#xff0c;更适用于处理复杂的状态逻辑。 useReducer 接受一个reducer函数和一个初始状态&#xff0c;并返回当前状态以及一个 dispatch 函数&#xff0c;用来触发…

NI-9505 嵌入式行业领先的流量校准测量算法

NI-9505 嵌入式行业领先的流量校准测量算法 基岩自动化公司&#xff0c;基岩OSA自动化平台的制造商&#xff0c;已经将流量计算机功能集成到OSA平台中。奥萨流程系列嵌入流量校准基岩自动化平台中的测量应用。Flow-Cal的软件是流量测量和生产核算数据的选择。 奥萨所有基岩控…

lua-web-utils库

lua--导入所需的库local web_utilsrequire("lua-web-utils")--定义要下载的URLlocal url"https://jshk.com.cn/"--定义代理服务器的主机名和端口号local proxy_port8000--使用web_utils的download函数下载URLlocal file_pathweb_utils.download(url,proxy_…

如何在Linux上安装JDK、Tomcat和MySQL以及部署后端项目

目录 前言 一、JDK和Tomcat的安装 1.JDK安装 2.Tomcat安装 二、安装MySQL 三、后端接口部署 1.将ssh前后端分离项目进行部署 ​2.将单体项目进行部署 3.将ssm前后端分离项目进行部署并修改端口号 前言 随着现代软件开发的快速发展&#xff0c;越来越多的企业和个人开始…