编程导航算法通关村——算法基础

news2024/9/23 23:34:40

目录

1. 时间复杂度

1.1. 时间复杂度概念

1.2. 几种常见的阶

1.2.1. 常数阶 O(1)

1.2.2. 线性阶 O(n)

1.2.3. 平方阶 (n²)

1.2.4. 对数阶 O(logn)

2. 最坏情况和平均情况

3. 空间复杂度


1. 时间复杂度

1.1. 时间复杂度概念

当我们说算法的时间复杂度时,我们通常是指执行该算法所需的基本操作次数,而不是实际的时钟时间。为了估算这个时间复杂度,我们通常会找出算法中的基本操作,并计算其执行次数。

以下是一个简单的Java代码示例,用于计算从1到n的所有数字之和:

public class SumUpToN {  
    public static int sum(int n) {  
        int sum = 0;  
        for (int i = 1; i <= n; i++) {  
            sum += i;  
        }  
        return sum;  
    }  
  
    public static void main(String[] args) {  
        int n = 100; // 举例n为100  
        System.out.println("Sum up to " + n + " is: " + sum(n));  
    }  
}

在这个例子中,基本操作是sum += i,它在for循环中执行了n次。因此,该算法的时间复杂度是O(n)。这表示,如果我们将输入大小(这里是n)翻倍,那么基本操作的执行次数也会大致翻倍。

需要注意的是,时间复杂度是一个估算值,用于比较不同算法的效率。实际的运行时间还会受到其他因素的影响,如硬件速度、编程语言、编译器优化等。


除了用次数表示时间进行简化,还有一个系数和参数方面的简化。
例如y=x+1,当x非常大时,1就可以忽略不计了,可以只保留y=x。
而如果y=x^2+x,当x非常大时,后面的+x作用也不大了,可以只保留y=x^2。
同理,y=3x^2和y=x^2+x+4 ,当x非常大时,此时前面的系数3和4的影响也不大,我们仍然可以只保留y=x^2。
此时可以只考虑不同的阶之间的变化情况,如下可以看到过了1之后,不同的表达式的差异将非常巨大。

需要记住的是常见的阶耗费时间的关系是:


1.2. 几种常见的阶

1.2.1. 常数阶 O(1)

一般顺序执行并且只执行一次的代码就是常数阶

常数阶(O(1))指的是算法的执行时间与输入数据的大小无关,也就是说,无论输入数据的大小如何,算法的执行时间都是固定的。

举例:

sum=sum+1;
sum=sum+2;
sum=sum+3;
sum=sum+4;

sum=sum+1;执行了4遍,即使重复了100次,也都是常数级,都用O(1)表示。


1.2.2. 线性阶 O(n)

线性阶表示执行的次数随着问题规模是线性变化的

线性阶(O(n))表示算法的执行时间与输入数据的大小n成正比。换句话说,当输入数据的大小n增加时,算法的执行时间也会线性地增加。

举例:

  • 使用for循环遍历数组:
int[] arr = {1, 2, 3, 4, 5};  
for(int i = 0; i < arr.length; i++){  
    System.out.println(arr[i]);  
}

这段代码会遍历数组arr并打印每个元素,所以它的执行次数与数组的长度成正比,是线性阶。

  • 使用while循环遍历数组:
int i = 0;  
int[] arr = {1, 2, 3, 4, 5};  
while(i < arr.length){  
    System.out.println(arr[i]);  
    i++;  
}

这段代码也会遍历数组arr并打印每个元素,所以它的执行次数与数组的长度成正比,是线性阶。

  • 使用递归函数计算阶乘:
public static int factorial(int n) {  
    if (n == 0) {  
        return 1;  
    } else {  
        return n * factorial(n - 1);  
    }  
}

这段代码使用递归函数计算给定数字的阶乘。虽然递归的次数与输入数据的大小n有关,但由于每次递归都会返回结果,所以整个递归过程的执行次数与n成正比,是线性阶。


1.2.3. 平方阶 (n²)

平方阶主要是双层循环嵌套。

int i,j;
for(i=0;i<n;i++){
 for(j=0;j<n;j++){
    //todo 时间复杂度为1的程序
    todo...
 }
}

上面的todo随着n是呈平方级别增加的,n是2,就执行4次,n是3就执行9次,所以是平方阶。

上面的例子可以变形为:

int i,j;
for(i=0;i<n;i++){
 for(j=i;j<n;j++){
    //todo 时间复杂度为1的程序
    todo 
 }
}

首先,外层循环会执行n次,这是很直观的,因为i从0到n-1,所以总共n次。

关键在内层循环。当我们看内层循环时,我们要注意j的起始值是i。这意味着,对于每一次外层循环的迭代,内层循环的次数都在减少。

例如:

  • 当i=0时,j从0到n-1,所以内层循环n次。
  • 当i=1时,j从1到n-1,所以内层循环n-1次。
  • 以此类推...
  • 当i=n-1时,j只从n-1到n-1,所以内层循环1次。

现在,我们要计算内层循环的总次数。这就像把上面列出的所有次数加起来:n + (n-1) + (n-2) + ... + 2 + 1。

这是一个等差数列的和。等差数列的和的公式是 n(n+1)/2。在这个情况下,它表示的是内层循环的总次数。

因此,整个嵌套循环的总执行次数就是 n(n+1)/2。当我们谈论时间复杂度时,我们通常关注最高阶的项,并忽略常数。

所以这里的时间复杂度也是O(n^2)。


1.2.4. 对数阶 O(logn)

二分查找,二叉树等问题经常会看到

其本质都可以简化成如下模型:

int count=1;
n=64
int items=0;
while(count<n){
   count=count*2;//todo注意看的是这行的执行次数与n的关系
   itmes++;
} 

count 代表当前的搜索范围的大小,每次迭代都会将 count 翻倍,直到 count 大于或等于 n。因此,每次迭代后,搜索范围会变成原来的两倍。

在上面的例子里,我们可以看一下todo的执行次数与count<n之间的关系:

todo执行次数
 

第一次
 

第二次
 

第三次
 

第四次
 

第五次
 

第六次
 

第七次
 

count
 

1
 

2
 

4
 

8
 

16
 

32
 

64

从上面可以看到,如果todo要执行第七次时,已经不满足count<n了,所以执行次数与n的关系正好是:2^x=n,也就是x=logn。

所以说,二分查找不过是每循环一次都是减半.所以todo的执行次数是logn次。


2. 最坏情况和平均情况

假设你有一组长度为n的随机数字,你希望通过一个算法快速找到其中的一个特定数字。在算法分析中,我们通常需要考虑三种情况:最好情况、最坏情况和平均情况。

  1. 最好情况:你已经知道目标数字位于数组的开头位置。在这种情况下,你只需要比较一次就能找到目标数字。在算法分析中,最好情况的时间复杂度是O(1),因为只需要进行一次比较。
  2. 最坏情况:你不知道目标数字在数组中的位置,而且它实际上位于数组的末尾。在这种情况下,你需要遍历整个数组才能找到目标数字。在算法分析中,最坏情况的时间复杂度是O(n),因为你需要进行n次比较才能找到目标数字。
  3. 平均情况:你不知道目标数字在数组中的确切位置,但你有一些关于它可能位于数组中部的线索。因此,你需要在数组中进行一些比较才能找到目标数字。平均情况下,你可能需要进行大约n/2次比较才能找到目标数字。在算法分析中,平均情况的时间复杂度可能是O(n/2),但实际上我们通常将其简化为O(n),因为大O表示法关注的是数量级而不是常数因子。

为了更好地理解这个例子,可以将搜索算法想象成在一排有序的书架上查找一本书。最好情况就是你知道书名并且它就在你眼前;最坏情况就是你需要从书架的一端到另一端逐一查找;平均情况则是你可能需要查看书架上的几个位置才能找到你要的书。

在选择和使用算法时,我们需要权衡这些因素,以确保算法在实际应用中的效率和稳定性。


3. 空间复杂度

空间复杂度则是指一个算法执行过程中所需要消耗的内存资源数量。它反映了算法的存储开销,同样也是

以一定的数学模型来表示。一个算法的空间复杂度越低,则其所需要的内存空间就越少。

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

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

相关文章

「完美世界」石昊被诓入至尊道场,修炼无敌道,打跑天仙书院弟子

Hello,小伙伴们&#xff0c;我是拾荒君。 《完美世界》这部国漫&#xff0c;在粉丝的翘首期盼中&#xff0c;终于迎来了第141集的更新。这一集的内容&#xff0c;对于喜欢石昊和至尊道场劫难的观众来说&#xff0c;可谓是扣人心弦&#xff0c;让人目不转睛。 在这一集中&#…

【node】使用 sdk 完成短信发送

实现效果 过程 流程比较复杂&#xff0c;加上需要实名认证&#xff0c;建议开发的时候先提前去认证号账号&#xff0c;然后申请模版也需要等认证。 源码 我看了新版的sdk用的代码有点长&#xff0c;感觉没必要&#xff0c;这边使用最简单的旧版的sdk。 https://github.com/…

【MySQL学习之基础篇】约束

文章目录 1. 概述2. 基础约束3. 外键约束3.1. 介绍3.2. 外键的添加3.3. 外键删除和更新行为 1. 概述 概念&#xff1a; 约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。     目的&#xff1a; 保证数据库中数据的正确、有效性和完整性。 分类&#x…

HHDESK个性化脚本功能

HHDESK可以把脚本配置在对话框中&#xff0c;生成按钮&#xff0c;便捷操作。 在界面下方的脚本框中&#xff0c;点击“”&#xff0c;选择新建&#xff1b; 随后在弹出框内填写名称及脚本&#xff0c;按需求选择填写参数&#xff0c;及运行过程中是否弹出参数框&#xff1b;…

Vue3-14- 【v-for】循环数组-解构的操作

说明 v-for 在遍历数组的时候&#xff0c;可以使用解构的语法&#xff0c;直接将数组中对象元素的属性解构出来&#xff0c; 从而实现直接使用对象属性值的效果。语法格式 &#xff1a; v-for"({属性名1,属性名2},索引变量名) in 数组名"具体的使用请看代码&#xf…

活动预告 | 微盟技术沙龙 - Elasticsearch 在微盟的实践 12/21/2023

微盟技术沙龙 「微盟技术沙龙」是由微盟研发中心发起并联合各方小伙伴为开发者举办的系列技术沙龙&#xff0c;从用户&#xff0c;产品&#xff0c;技术等方面与开发者进行交流。 微盟技术沙龙关注开发者在实际应用中遇到的问题。提供最真实的干货&#xff0c;以技术会友&…

北京通用人工智能研究院提出了首个三维世界中的具身多任务多模态的通才智能体 LEO

想要迈向通用人工智能&#xff0c;必须要构建一个能够理解人类生活的真实世界&#xff0c;并掌握丰富技能的具身通用智能体。 今年以来&#xff0c;以 GPT-4 (V)[1]、LLaVA [2]、PALM-E [3] 等为代表的多模态大语言模型&#xff08;Multi-modal Large Language Model&#xff…

Qt 数据库QSqlDatabase使用记录

记录一些在QT中使用QSqlDatabase操作数据库时&#xff0c;需要注意的地方 创建数据库 bool CDBOperatorAbstract::_openDBConn(CDatabaseConfig config) {QWriteLocker locker(&m_locker);QSqlDatabase db;if(QSqlDatabase::contains(m_connectionName)){db QSqlDatabas…

随机森林1(了解整体知识架构)

很多人想学习或者了解随机森林&#xff0c;查到的资料都是先讲熵&#xff0c;再讲决策树&#xff0c;然后再讲随机森林&#xff0c;前面坚持不下来或者一个地方没理解透彻&#xff0c;导致无法向下学习&#xff0c;而且公式讲解不够清晰&#xff0c;例子不够详细&#xff0c;很…

AI+高通量生物数据构造精准靶向肿瘤的人工合成病毒

David-Baker 创新点&#xff1a; - 学科交叉 - 从基础到应用 - 合成生物AI模型

孟德尔随机化+WGCNA+预后模型,7+轻松get

今天给同学们分享一篇生信文章“Exploring the causality and pathogenesis of systemic lupus erythematosus in breast cancer based on Mendelian randomization and transcriptome data analyses”&#xff0c;这篇文章发表在Front Immunol期刊上&#xff0c;影响因子为7.3…

Selenium+Python实现自动化测试,看完就会。。。

安装selenium 打开命令控制符输入&#xff1a;pip install -U selenium 火狐浏览器安装firebug&#xff1a;www.firebug.com&#xff0c;调试所有网站语言&#xff0c;调试功能 Selenium IDE 是嵌入到Firefox 浏览器中的一个插件&#xff0c;实现简单的浏览器操 作的录制与回…

CMake创建wxWidgets桌面应用

CMake创建wxWidgets桌面应用 环境 Windows 10CMake 3.28MinGW 64 8.1wxWidgets 3.2.4 wxWidgets GitHub: https://github.com/wxWidgets/wxWidgets/文档地址: https://docs.wxwidgets.org/stable/page_topics.html下载地址&#xff1a;https://www.wxwidgets.org/downloads…

后端项目操作数据库-中枢组件Service调用Mapper实现增删改查-实例

接上篇 使用MyBatis配置Mapper实现增删改查 1.Service的基本作用 Service在代码中的的作用是调用Mapper、被Controller调用。是后端项目中非常重要的组件。 用于设计业务流程、业务逻辑&#xff0c;以保障数据的完整性、有效性、安全性。 2. Service使用举例——“添加相册”…

生物信息学分析领域领先的特制语言环境NGLess(Next Generation Less)介绍、安装配置和详细使用方法

介绍 NGLess&#xff08;Next Generation Less&#xff09;是一种用于生物信息学分析的领先的领域特定语言&#xff08;DSL&#xff09;。它旨在简化和加速NGS&#xff08;Next Generation Sequencing&#xff09;数据的分析过程。NGLess具有清晰的语法和功能&#xff0c;使用户…

宝塔面板快速搭建本地网站结合内网穿透实现远程访问【无需公网IP】

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 前言 宝塔面板作为简单好用的服务器运维管理面板&#xff0c;它支持Linux/Windows系统&#xff0c;我们可用它来一键配置LAMP/LNMP环境、网站、数据库、FTP等&…

OpenAI | GPT-4.5“泄露”,价格离谱!

OpenAI “泄露”了GPT-4.5&#x1f440; 最近&#xff0c;OpenAI “泄露”了备受期待的 GPT-4.5 这个最新的模型带来了跨语言、音频、视觉、视频和3D的多模态功能&#xff0c;开启了复杂推理和跨模态理解的新篇章。 新模型系列包括&#xff1a; GPT-4.5&#xff1a;标准版&…

LeetCode977有序数组的平方两种方法实现(java实现)

今天来分享的是LeetCode977有序数组的平方的实现方法&#xff0c;我们先来看下题目&#xff1a; 提示&#xff1a;我们在读题的时候一定要仔细&#xff0c;注意题目给定的条件是有序数组。 方法1&#xff1a;我们在看到题目的第一时间是无非是将数组每个元素进行平方&#xff…

防御升级!SMC2助力企业高效应对邮箱安全挑战

根据Coremail邮件安全人工智能实验室&#xff08;以下简称AI实验室&#xff09;的监测数据显示&#xff0c;2023年Q3全国企业级用户遭受无差别的暴力破解攻击次数虽相比2022年同期有所下降&#xff0c;但仍高达 24.2 亿次&#xff0c;且暴力破解攻击次数有明显回升趋势。 面对正…

关东升老师从小白到大牛系列丛书(由清华大学出版社出版)

助力技术成长&#xff0c;成就大牛之路 在这个科技日新月异的时代&#xff0c;掌握一门编程语言或专业技能已是必备&#xff0c;不再是奢侈。清华大学出版社出版的“从小白到大牛”的系列丛书&#xff0c;涵盖Python、Java、Kotlin、Android和SQL&#xff0c;助你快速在技术之…