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

目录

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. 空间复杂度

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

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

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

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

相关文章

【动手学深度学习】(十四)数据增广+微调

文章目录 一、数据增强1.理论知识2.代码 二、微调1.理论知识 一、数据增强 1.理论知识 增加一个已有数据集&#xff0c;使得有更多的多样性 在语言里面加入各种不同的背景噪音改变图片的颜色和形状 使用增强数据训练 翻转 左右翻转上下翻转 不总是可行 切割 从图片中切…

【数据结构和算法】判断子序列

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;双指针 三、代码 3.1 方法一&#xff1a;双指针 3.1.1 Java易懂版&#xff1a;…

解决Chrome同一账号在不同设备无法自动同步书签的问题

文章目录 一、问题与原因&#xff1f;2. 解决办法 一、问题与原因&#xff1f; 1.问题 使用谷歌Chrome浏览器比较头疼的问题就是&#xff1a;使用同一个Google账号&#xff0c;办公电脑与家用电脑的数据无法同步。比如&#xff1a;办公电脑中的书签、浏览记录等数据&#xff0…

drf入门规范

一 Web应用模式 在开发Web应用中&#xff0c;有两种应用模式&#xff1a; 1.1 前后端不分离 1.2 前后端分离 二 API接口 为了在团队内部形成共识、防止个人习惯差异引起的混乱&#xff0c;我们需要找到一种大家都觉得很好的接口实现规范&#xff0c;而且这种规范能够让后端写…

Tomcat部署与调优

目录 前瞻 什么是tomcat&#xff1f; 什么是servlet&#xff1f; 什么是JSP? Tomcat功能组件结构 Container结构分析 Tomcat请求过程 Tomcat服务部署 1.关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下 2.安装JDK 3.设置JDK环境变量 4.安装启动Tomc…

1130 - Host “WIN-CA4FHERGO9J‘ is not allowed to connect to this MySQL server

1、知识小课堂 1.1 Mysql MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB公司开发&#xff0c;属于Oracle旗下产品。它是最流行的关系型数据库管理系统之一&#xff0c;在WEB应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management System&am…

[每周一更]-(第27期):HTTP压测工具之wrk

[补充完善往期内容] wrk是一款简单的HTTP压测工具,托管在Github上,https://github.com/wg/wrkwrk 的一个很好的特性就是能用很少的线程压出很大的并发量. 原因是它使用了一些操作系统特定的高性能 io 机制, 比如 select, epoll, kqueue 等. 其实它是复用了 redis 的 ae 异步事…

逻辑回归代价函数

逻辑回归的代价函数通常使用交叉熵损失来定义。这种损失函数非常适合于二元分类问题。 本篇来推导一下逻辑回归的代价函数。 首先&#xff0c;我们在之前了解了逻辑回归的定义&#xff1a;逻辑回归模型是一种用于二元分类的模型&#xff0c;其预测值是一个介于0和1之间的概率…

都有哪些大厂开始适配鸿蒙原生应用呢

12月8日&#xff0c;随着支付宝宣布启动鸿蒙原生应用开发以来&#xff0c;国内宣布接入鸿蒙原生应用开发的公司越来越多。事实上&#xff0c;自9月华为宣布鸿蒙原生应用全面启动以来&#xff0c;已有金融、旅行、社交等多个领域的企业和开发者陆续宣布加入鸿蒙生态&#xff0c;…

twitter开发如何避坑

此篇介绍在twitter开发过程中遇到的坑&#xff08;尤其是费用的坑&#xff09;。 一坑&#xff1a;免费接口少&#xff01; 刚开始申请免费API使用的时候&#xff0c;twitter官方只会给你三个免费接口使用。 发twitter、删推文、查看用户信息。 这三个接口远远不够开发中使用…

例如,用一个DatabaseRow类型表示一个数据库行(容器),用泛型Column<T>作为它的键

以下是一个简单的示例&#xff0c;演示如何使用泛型的Column<T>作为DatabaseRow的键&#xff0c;表示一个数据库行&#xff08;容器&#xff09;&#xff1a; // 列定义 class Column<T> {private String columnName;private T value;public Column(String column…

将 Github token 添加至远程仓库

将 Github token 添加至远程仓库后便于每次 push 重复输入的麻烦 首先,将已生成的 token 记录(注:生成后的 token 确认后便无法查看只能重新生成)并找到对应的项目 git 本地文件路径下 其次,将其与项目所关联,按如下格式配置即可 token 格式类似于 ghp_CAxxxxxxxxxxxxxxxxxGx5j…

Linux 虚拟机复制后如何彻底修改ip共存

Linux那些事儿 1、复制 2、连接 3、cd /etc/sysconfig/network-scripts/ 4、ls -a 5、vi ifcfg-eth0 6、i 7、修改mac地址和ip地址&#xff0c;记住修改后的mac&#xff08;重要&#xff09; 8、关机 9、打开虚拟机设置此镜像&#xff1a;

Centos系统pnpm升级报错 ERR_PNPM_NO_GLOBAL_BIN_DIR

在 CentOS 系统中使用 pnpm i -g pnpm 报错&#xff1a;ERR_PNPM_NO_GLOBAL_BIN_DIR Unable to find the global bin directory&#xff0c;折腾半天终于解决了。 完整报错信息 [rootVM-8 test]# pnpm i -g pnpm Nothing to stop. No server is running for the store at /roo…

【自动化测试】web3py 连接 goerli

web3py 连接 goerli 直接使用库里方法 if __name__ __main__:from web3.auto.infura.goerli import w3w3.eth.get_balance(get_address_by_private_key(os.getenv("AAA_KEY")))error info: websockets.exceptions.InvalidStatusCode: server rejected WebSocket …

Appium 图像识别技术 OpenCV

在我们做App自动化测试的时候&#xff0c;会发现很多场景下元素没有id、content-desc、text等等属性&#xff0c;并且有可能也会碰到由于开发采用的是自定义View&#xff0c;View中的元素也无法识别到&#xff0c;很多的自动化测试框架对此类场景束手无策。Appium在V1.9.0中有给…

[Linux] Tomcat部署和优化

一、Tomcat相关知识 1.1 Tomcat的简介 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;是 Apache 软件基金会的 Jakarta 项目中的一个核心项目&#xff0c;由 Apache、Sun 和其他一些公司及个人共同开发而成。 …

Axure动态面板的使用

一. 动态面板 Axure动态面板是Axure RP软件中的一个功能模块&#xff0c;用于创建交互式原型和模拟应用程序的动态效果。它可以模拟用户在应用程序中的操作流程&#xff0c;并展示不同状态之间的变化&#xff0c;提供更真实的用户体验。通过创建不同的状态和添加交互效果&…

Jupyter Notebook的使用

Jupyter Notebook的使用 Jupyter Notebook是Anaconda自带的一款非常不错的代码编辑器&#xff0c;非常适合Python初学者使用&#xff0c;它有如下特点&#xff1a; 可以非常方便地将代码分区块运行&#xff1b; 运行结果可以自动保存&#xff0c;不需要在之后重复运行代码&…