踏“时间”与“空间”前来探寻复杂度的奥妙(Java篇)

本篇会加入个人的所谓‘鱼式疯言’

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言
而是理解过并总结出来通俗易懂的大白话,
小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.
🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

前言

小伙伴们有没有想过一个问题,在我们做算法过程中,

你是不是有很多种算法思想呢 😊 😊 😊

那这些算法好还是更好呢,我们该怎么衡量呢,这时我们就需要两个维度来衡量:

那就是我们本篇文章要学习的 时间复杂度和空间复杂度

目录

  1. 算法效率
  2. 时间复杂度
  3. 空间复杂度

一. 算法效率

算法效率分析分为两种:

第一种是时间效率,第二种是空间效率。

时间效率被称为时间复杂度,而空间效率被称作空间复杂度。

时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,

在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。

但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

鱼式疯言

两句话总结一下

我们用时间复杂度和空间复杂度两个概念来衡量算法的高效性

目前我们更关注时间复杂度

二. 时间复杂度

1. 时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个数学函数,它定量描述了该算法的运行时间。

一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。

但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。

一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

2.时间复杂度的计算方法

计算方法: 大O的渐进表示法

<1>. 举个栗子

public class J3_20 {void func1(int N){int count = 0;for (int i = 0; i < N ; i++) {for (int j = 0; j < N ; j++) {count++;}}for (int k = 0; k < 2 * N ; k++) {count++;}int M = 10;while ((M--) > 0) {count++;}System.out.println(count);}
}

从上面这段代码我们可以计算出

Func1 执行的基本操作次数:

F(N)= N^2+s*N+10

那么我们可以推导出

  • N=10 F(N)=130
  • N=100 F(N)=10210
  • N=1000 F(N)=1222010

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数

而只需要大概执行次数,那么这里我们 使用大O的渐进表示法。

大O符号(Big O notation):是用于描述 函数渐进行为的数学符号。

<2>. 推导大O阶方法

先了解下我们大O 阶法的原则吧 💖 💖 💖

1、用常数1取代运行时间中的所有加法常数。

2、在修改后的运行次数函数中,只保留最高阶项。

3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

所以上题使用大O的渐进表示法以后,Func1的时间复杂度为

N = 10 F(N) = 100

N = 100 F(N) = 10000

= 1000 F(N) = 1000000

故使用大O的渐进表示法去掉了那些对结果影响不大的项 ,简洁明

的表示出了执行次数

其次有些算法的时间复杂度存在最好,平均和最坏情况:

最坏情况:任意输入规模的最大运行次数(上界)

平均情况:任意输入规模的期望运行次数

最好情况:任意输入规模的最小运行次数(下界)

such:在一个长度为N数组中搜索一个数据x

最好情况:1次找到

最坏情况:N次找到

平均情况:N/2次找到

鱼式疯言

在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

宝子们可以想想,我们执行最坏的结果也就不就包含了所有可能发现的情况了嘛, 所以我们才这么做 💖 💖 💖

3. 时间复杂度的具体计算

<1>. 非递归

栗子 one
// 计算func2的时间复杂度?
void func2(int N) {
int count = 0;
for (int k = 0; k < 2 * N ; k++) {
count++;
}
int M = 10;
while ((M--) > 0) {
count++;
}
System.out.println(count);
}

在栗子中

基本操作执行了2N+10次通过推导大O阶方法知道,时间复杂度为 O(N)

栗子 two
// 计算func3的时间复杂度?
void func3(int N, int M) {
int count = 0;
for (int k = 0; k < M; k++) {
count++;
}
for (int k = 0; k < N ; k++) {
count++;
}
System.out.println(count);
}

在栗子中

基本操作执行了M+N次,有两个未知数M和N,时间复杂度为 O(N+M)

栗子 three
// 计算func4的时间复杂度?
void func4(int N) {
int count = 0;
for (int k = 0; k < 100; k++) {
count++;
}
System.out.println(count);
}

在本题中

3基本操作执行了 100次,通过推导大O阶方法,时间复杂度为 O(1)

栗子 four
// 计算bubbleSort的时间复杂度?
void bubbleSort(int[] array) {
for (int end = array.length; end > 0; end--) {
boolean sorted = true;
for (int i = 1; i < end; i++) {
if (array[i - 1] > array[i]) {
Swap(array, i - 1, i);
sorted = false;
}
}
if (sorted == true) {
break;
}
}
}

在本栗子中

在这里插入图片描述

基本操作执行最好N次

最坏执行了**(N*(N-1))/2次**

通过推导 大O阶方法+时间复杂度一般看最坏,时间复杂度为 O(N^2)

栗子 five
// 计算binarySearch的时间复杂度?
int binarySearch(int[] array, int value) {
int begin = 0;
int end = array.length - 1;
while (begin <= end) {
int mid = begin + ((end-begin) / 2);
if (array[mid] < value)
begin = mid + 1;
else if (array[mid] > value)
end = mid - 1;
else
return mid;
}
return -1;
}

在本栗子中

在这里插入图片描述

基本操作执行最好1次,最坏log2N次,时间复杂度为 O( ) ps

在算法分析中表示是 底数为2,对数为N,有些地方会写成lgN。

(建议通过折纸查找的方式讲解logN是怎么计算出来的)
(因为二分查找每次排除掉一半的不适合值,一次二分剩下:n/2两次二分剩下:n/2/2 = n/4)

鱼式疯言

计算非递归时间复杂度的两点秘诀

1. 看代码
2. 看思想

<2>. 递归

说到递归代码,我们该怎么算呢 ? ? ?

其实也不难

递归复杂度= 递归次数 每次代码执行次数*

栗子 one
// 计算阶乘递归factorial的时间复杂度?
long factorial(int N) {
return N < 2 ? N : factorial(N-1) * N;
}

在本栗子中
在这里插入图片描述

通过计算分析发现基本操作 递归了N次,时间复杂度为O(N)。

栗子 two
// 计算斐波那契递归fibonacci的时间复杂度?
int fibonacci(int N) {
return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}

在本栗子中

在这里插入图片描述

通过计算分析发现基本操作递归了2^n 次,时间复杂度为O( 2^n )。

鱼式疯言

总结两句

计算时间复杂度,一要看算法思想,二要看具体代码

递归复杂度 = 递归次数 * 每次代码执行次数

三. 空间复杂度

因为就目前而言,对于算法题的 空间复杂度要求不是很高,

所以小编在这里只是简单介绍一下哦,小伙伴们了解即可

1. 空间复杂度简介

空间复杂度是对 一个算法在运行过程中临时占用存储空间大小的量度 。

空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以 空间复杂度算的是变量的个数。

空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。

2. 栗子one

// 计算bubbleSort的空间复杂度?
void bubbleSort(int[] array) {
for (int end = array.length; end > 0; end--) {
boolean sorted = true;
for (int i = 1; i < end; i++) {
if (array[i - 1] > array[i]) {
Swap(array, i - 1, i);
sorted = false;
}
}
if (sorted == true) {
break;
}
}
}

在本栗子中

使用了常数个额外空间,所以空间复杂度为 O(1)

栗子two

// 计算fibonacci的空间复杂度?
int[] fibonacci(int n) {
long[] fibArray = new long[n + 1];
fibArray[0] = 0;
fibArray[1] = 1;
for (int i = 2; i <= n ; i++) {
fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
}
return fibArray;
}

在本栗子中

动态开辟了N个空间,空间复杂度为 O(N)

鱼式疯言

一句话明了

空间复杂度中,主要以多少个类型数据来粗略计算

总结

  • 算法效率: 了解一个好的算法的两点衡量标准的概念
  • 时间复杂度: 明了了时间复杂度的概念并熟悉掌握了大O渐进表示法的要义
  • 空间复杂度: 知晓了空间复杂度并学会了如何粗略的计算

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

校园综合能效平台建设的意义

彭姝麟 Acrelpsl 一 高校用能分析 当前高校用能普遍存在以下点问题&#xff1a; 一是用能需求日益增加&#xff1a;随着高校的快速发展&#xff0c;校园用能人数、用能设备、建筑面积等逐年增加&#xff0c;用能需求也相应攀升。日益增长的能耗需求与节能降耗任务之间的客观矛…

一文读懂什么是序列 (sequence)

sequence 序列 sequence(序列)是一组有顺序的元素的集合 (严格的说&#xff0c;是对象的集合&#xff0c;但鉴于我们还没有引入“对象”概念&#xff0c;暂时说元素) 序列可以包含一个或多个元素&#xff0c;也可以没有任何元素。 我们之前所说的基本数据类型&#xff0c;都…

蓝桥杯练习03个人博客

个人博客 介绍 很多人都有自己的博客&#xff0c;在博客上面用自己的方式去书写文章&#xff0c;用来记录生活&#xff0c;分享技术等。下面是蓝桥云课的博客&#xff0c;但是上面还缺少一些样式&#xff0c;需要大家去完善。 准备 开始答题前&#xff0c;需要先打开本题的…

物业社区人行通道闸如何选择,这6点一定要考虑!

社区是居民的共同家园&#xff0c;一个安全、便捷且和谐的社区环境对于提升居民的生活质量至关重要。人行通道闸不仅仅是一道简单的进出关卡&#xff0c;它是守护社区人员通行安全的坚实屏障&#xff0c;是提升社区管理效率的智能工具&#xff0c;更是增强业主满意度的关键因素…

C# 部署ICE框架以及用例(VS2019)

使用Windows 10环境&#xff0c;VS2019进行ICE用例开发 用例结构&#xff1a;客户端和服务端 关键技术&#xff1a;集成ICE环境&#xff0c;可以创建ice文件并自动生成对应的cs文件 1.环境安装 ICE Build插件安装。安装以后&#xff0c;就可以在项目中插入ice文件 2.代码实…

放大镜效果

放大镜效果 摘要 利用css和js来实现图片放大效果 HTML <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…

Go——切片

1. 特点 slice并不是数组或数组指针。它通过内部指针和相关属性引用数组片段&#xff0c;以实现变长方案。 切片&#xff1a;切片是数组的一个引用&#xff0c;因此切片是引用类型。但自身是结构体&#xff0c;值拷贝传递。切片的长度可以改变&#xff0c;因此&#xff0c;切片…

Elasticsearch实战:索引阻塞 —— 数据保护的终极武器

文章目录 1、索引阻塞的种类2、什么时候使用阻塞&#xff1f;场景1&#xff1a;进行系统维护场景。场景2&#xff1a;保护数据不被随意更改场景。场景3&#xff1a;优化资源使用的场景。场景4&#xff1a;遵守安全规则场景。 3、添加索引阻塞API4、解除设置 API5、小结6、参考 …

Transformer位置编码(Position Embedding)理解

本文主要介绍4种位置编码&#xff0c;分别是NLP发源的transformer、ViT、Sw-Transformer、MAE的Position Embedding 一、NLP transformer 使用的是1d的绝对位置编码&#xff0c;使用sincos将每个token编码为一个向量【硬编码】 Attention Is All You Need 在语言中&#xff0…

RPG Maker MV 踩坑八 仿新仙剑战斗物品指令菜单

仿新仙剑战斗物品指令菜单 遇到的坑坑一坑二解决方法 遇到的坑 上次做的额外战斗指令菜单和物品战斗指令菜单&#xff0c;突然发现一个大问题&#xff0c;漏风了&#xff01;&#xff01;&#xff01; 其实就是将底部漏出来了&#xff0c;这样整个UI就不完整了&#xff0c;算是…

微服务day04(上)-- RabbitMQ学习与入门

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但…

深度学习 | 神经网络

一、神经网络原理 1、神经元模型 虽然叫个神经元&#xff0c;但骨子里还是线性模型。 2、神经网络结构 顾名思义就是由很多个神经元结点前后相连组成的一个网络。虽然长相上是个网络&#xff0c;但是本质上是多个线性模型的模块化组合。 在早期也被称为 多层感知机 Multi-Layer…

Visual Studio 2013 - 调试模式下根据内存地址查看内存

Visual Studio 2013 - 调试模式下根据内存地址查看内存 1. 查看内存References 1. 查看内存 调试 -> 窗口 -> 内存 -> 内存1-4 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【质押空投】公链Zkasino

据深潮TechFlow报道&#xff0c;游戏公链Zkasino HyperChain宣布上线质押挖矿活动&#xff0c;参与者可通过将ETH跨链到Zkasino链的方式来获取ZKAS代币。本次活动总共将分配25%的总代币供应量给参与者。质押挖矿时间将通过倒计时的方式来限制参与人数&#xff0c;以保护早期质押…

Datawhale 零基础入门数据挖掘-Task1 赛题理解

一、 赛题理解 Tip:此部分为零基础入门数据挖掘的 Task1 赛题理解 部分&#xff0c;为大家入门数据挖掘比赛提供一个基本的赛题入门讲解&#xff0c;欢迎后续大家多多交流。 赛题&#xff1a;零基础入门数据挖掘 - 二手车交易价格预测 地址&#xff1a;零基础入门数据挖掘 -…

【代码分享】四十七种测试函数(关注可免费获取)

智能优化算法测试函数简介 智能优化算法测试函数是为了在优化算法研究和开发中测试算法性能的规范问题集合。这些测试函数模拟了真实世界优化问题的不同方面,包括局部最小值、最大值、全局最优解,以及多种复杂性如高维度、非线性、不连续等。优化算法,如遗传算法、粒子群优…

蓝桥杯之动态规划冲刺

文章目录 动态规划01背包小练一下01背包网格图上的DP完全背包 最长公共字符串最长递增子序列 动态规划 动态规划&#xff1a;确定好状态方程&#xff0c;我们常常是确定前 当状态来到 i 时&#xff0c;前 i 个物体的状态是怎么样的&#xff0c;我们并不是从一个点去考虑&#x…

数据库基本介绍及编译安装mysql

目录 数据库介绍 数据库类型 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统 DBMS的工作模式 关系型数据库的优缺点 编译安装mysql 数据库介绍 数据&#xff1a;描述事物的的符号纪录称为数据&#xff08;Data&#xff09; 表&#xff1a;以行和列的形式组成…

mysql迁移达梦数据库 Java踩坑合集

达梦数据库踩坑合集 文章目录 安装达梦设置大小写不敏感Spring boot引入达梦驱动&#xff08;两种方式&#xff09;将jar包打入本地maven仓库使用国内maven仓库&#xff08;阿里云镜像&#xff09; 达梦驱动yml配置springboot mybatis-plus整合达梦,如何避免指定数据库名&…

常用负载均衡详解

一、介绍 在互联网场景下&#xff0c;负载均衡&#xff08;Load Balance&#xff09;是分布式系统架构设计中必须考虑的一个环节&#xff0c;它通常是指将负载流量&#xff08;工作任务、访问请求&#xff09;平衡、分摊到多个操作单元&#xff08;服务器、组件&#xff09;上去…