当前位置: 首页 > java >正文

复杂度讲解

1、算法好坏的度量

【事前分析法】
算法设计好后,根据算法的设计原理,只要问题规模确定,算法中基本语句执⾏次数和需求资源个数
基本也就确定了。
比如求 1 + 2 + 3 + ... + n − 1 + n ,可以设计三种算法:
算法A:
const int N = 1e5 + 10;
int a[N];
int sum(int n)
{// 先把 1 ~ n 存起来for(int i = 1; i <= n; i++){a[i] = i;}// 循环逐个数字相加int ret = 0;for(int i = 1; i <= n; i++){ret += a[i];}return ret;
}
需要开辟⼀个大小为 N 的空间。

 算法B:

int sum(int n)
{// 循环逐个数字相加int ret = 0;for (int i = 1; i <= n; 
i++) {ret += i;}return ret;
}

不需要开辟空间,直接求和。

需要循环 n 次, ret + = n 语句会执行  n 次 ,而且随着问题规模的增长,执行次数也会增长。
算法执行所需资源的个数与问题规模有关。因此可以根据算法执行过程中对空间的消耗来衡量算法
的好坏,这就是空间复杂度。

算法C:

int sum(int n)
{// 利⽤求和公式return (1 + n) * n / 2;
}
不论问题规模为多少, 语句只会执行1次。
算法中基本语句总的执行次数与问题规模有关。因此可以根据算法执行过程中,所有语句被执行的
次数之和来衡量算法的好坏,这就是时间复杂度。
综上所述,时间和空间的消耗情况就是我们度量⼀个算法好坏的标准,也就是时间复杂度和空间复杂度。

2、时间复杂度

在计算机科学中,算法的时间复杂度是⼀个函数式T ( N ) ,它定量描述了该算法的运行时间。这个
T ( N )函数式计算了程序中语句的执行次数。
案例:计算⼀下 fun 中 ++count 语句总共执行了多少次?
void fun(int N) 
{ int count = 0; for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { ++count; // 执⾏次数是 n*n,也就是 n^2} } for(int k = 0; k < 2 * N; k++) {++count; // 执⾏次数是 2*n} int M = 10; while(M--) { ++count; // 执⾏次数 10} 
}
fun 函数 ++count 语句的总执行次数:
T ( N ) = N 2 + 2 × N + 10

大O表示法

在上述案例中,对取值进行分析,随着N的增大,对结果影响最大的⼀项是N^2 ,2N和10
可以忽略不计,算法执行时间的增长率与T ( N )中的 N^2的增长率基本⼀致。
因此,在计算时间复杂度的时候,⼀般会把T ( N ) 中对结果影响不大的项忽略掉,该种表示时间复杂度的方式称为大O渐进时间复杂度 - 这是一种粗略的估计方式,只看影响时间开销最大的⼀项。
O ( T ( N )) = O ( N ^2   + 2 N + 10)
所以对于上述 fun 函数,其时间复杂度为 O ( T ( N )) = O ( N ^2   + 2 N + 10) ,取最高阶项最终为:
O ( N ^ 2 )
推导大O渐进时间复杂度的规则
1. 时间复杂度函数式 T ( N ) 中,只保留最高阶项,去掉那些低阶项;
2. 如果最高阶项存在且不是 1 ,则去除这个项目的常数系数;
3. T ( N ) 中如果没有 N 相关的项目,只有常数项,用常数 1 取代所有加法常数。

最优、平均和最差时间复杂度

案例:在 n 个整形元素数组中,检测 x 是否存在,若存在返回其在数组中的下标,否则返回 −1
int find (int a[], int n, int x)
{for (int i = 0; i < n; i++){if (a[i] == x) return i;}return -1;
}

在查找过程中,需用  x 与数组中元素依次比较,因此总的比较次数就是该算法的时间复杂度。则:
若待查找元素 x 21 ,只需要比较 1 次,为算法的最优(好)情况。
若带查找元素 x 17 ,或者是不存在的元素,需要比较 n 次,为算法的最坏(差)情况。
所有情况的比较次数之和,除以总情况,为算法的平均情况。
查找第⼀个元素需比较1次,查找第2个元素需比较2次,...,查找第n个元素需比较n次,假
设每个元素查找的概率相同,则平均比较次数为
1+2+3+...+n=(1+n)/2。
最好时间复杂度为 O (1)
最坏时间复杂度为 O ( n )
平均时间复杂度为 ,也就是O ( n ) 。
但是,无论是在竞赛还是工程中,算法的时间复杂度⼀般为最差情况。因为最差情况是人对⼀件事情所能承受的底线,因此 find 算法的时间复杂度为 O ( n )

3、空间复杂度

有了时间复杂度的铺垫,空间复杂度的计算就比较容易了。
在算法竞赛中,空间复杂度就是整个程序在解决这个问题时,⼀共使用了多少空间。
案例一:冒泡排序
#include <iostream>
using namespace std;
const int N = 20;
int arr[N];
int main()
{int n = 0;cin >> n;int i = 0;//输⼊for(i=0; i < n; i++)cin >> arr[i];//排序for(i = 0; i < n-1; i++){int j = 0;for(j = 0; j <= n-1-i; j++){if(arr[j] < arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp; }}} //输出for(i=0; i < n; i++){cout << arr[i] << endl;}return 0;
}
空间复杂度:需要⼀个和问题规模⼀致的数组来存数据。因此空间复杂度为 O ( N )
http://www.xdnf.cn/news/8679.html

相关文章:

  • [yolov11改进系列]使用轻量级骨干网络MobileNetV4替换backbone的python源码+训练源码+改进流程+改进原理
  • 如何进行CAN一致性测试
  • 解决:ERROR: No matching distribution found for matplotlib= =3.8.3
  • 算法学习笔记·数学·快速幂
  • M00282-P2并联混合动力电动汽车的电池充电持续能源管理系统
  • 楼宇自控成建筑领域关键技术,为实现建筑碳中和注入强劲技术动能
  • DELL EMC PowerStore BBU更换手册
  • 【踩坑记录】nvidia-smi 能识别 GPU,但 torch.cuda.is_available() 报错的终极解决方案
  • 【MPC控制 - 从ACC到自动驾驶】2 车辆纵向动力学建模与离散化:MPC的“数字蓝图”
  • 初学c语言20(动态内存管理)
  • 浅析SpringBoot中的classpath
  • C++——volatile
  • C#学习第25天:GUI编程
  • 视频剪辑 VEGAS - 配置视频片段保持原长宽比
  • 2025 中青杯数学建模AB题
  • 加州房价预测:基于 Python 的多元回归分析实践
  • PP-YOLOE-SOD学习笔记2
  • ruoyi-erp 开源:功能全面灵活可定制
  • 25Yunxi期中
  • 基于CSP模型实现的游戏排行榜
  • 【Qt开发】进度条ProgressBar和日历Calendar Widget
  • 消息队列在异步推理任务中的作用
  • leetcode hot100刷题日记——14.二叉树的最大深度
  • pyhton基础【2】基本语法
  • CodeForces - 1692D
  • 算法笔记·数学·欧拉函数
  • PCB布局设计
  • Windows逆向工程提升之IMAGE_BASE_RELOCATION
  • 使用Python操作Mysql数据库
  • 【VBA 字典的引用和调用方法】