对时间复杂度和空间复杂度的理解

时间复杂度

在算法中,所谓的时间复杂度可以简单的理解成为算法的运行时间。接下来我们可以简单的去看一下时间复杂度是怎么计算的

例子:
javascript 复制代码
function print1() {
  console.log('打印')
}
// 函数内代码只执行了1次

function print2(n) {
  for (let i = 0; i < n; i++) {
    console.log('打印')
  }
}

第一个 print1 很明显的看出来只执行了1次

第二个函数:对于print2 我们可以先假设 **n = 2

**

回到 n 这个数上,我们再计算一下执行了几次

可以得出结果就是 一共执行了 3n + 2次

结论

通常一段代码的总执行次数,我们会用T(n)来表示, 而如果n的数据比较大时,T(n)来表达就不是很合适。在算法中,我们通常会用T(n)的简化估算值 来计算代码的运行速度,而这个估算值就被称为时间复杂度。

T(n) --> 时间复杂度
  • print1 = T(n) = 1 --> 对于T(n)是个常数时,可以直接将其估算成 1 --> O(1)
  • print2 = T(n) = 3n + 2 --> 如果n足够大的时候,可以理解成忽略其常数和n前面的系数,也就n --> O(n)
  • 补充: T(n) = 4n^8 + 10n^7 + 2 -->同样的道理,n足够大时,取n的次方最大作为复杂度--> O(n^8)

常见的例子
例子1:
js 复制代码
function print1() {
  console.log('打印1') // 打印了一次
  console.log('打印2') // 打印了一次
  console.log('打印3') // 打印了一次
  console.log('打印4') // 打印了一次
  console.log('打印5') // 打印了一次
}
// 复杂度 O(1)
例子2:
js 复制代码
function print2(n) {
  for (let i = 0; i < n; i++) {
    console.log('打印') // 打印了一次
  }
}
// 复杂度 O(n)

可以简单总结出来:代码存在多少层循环,时间复杂度就是多少。

例子3:
js 复制代码
function print3(n) {
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      console.log('打印') // 打印了一次
    }
  }
  for (let k = 0; k < n; k++) {
    console.log('打印') // 打印了一次
  }
}
// 当 i = 0,内部会执行 n + 1 次, i = 1, 持续 2n + 2,依次类推,应该会执行个 n*n + n = n^2+n 次。
// 复杂度为O(n^2)
例子4:
js 复制代码
function print4(n) {
  if (n > 100) {
    for (let i = 0; i < n; i++) {
      for (let j = 0; j < n; j++) {
        console.log('打印') // 打印了一次
      }
    }
  } else {
    for (let i = 0; i < n; i++) {
      console.log('打印') // 打印了一次
    }
  }
  
}
// 如果是存在判断条件,则还是以最长运行时间最为最终结果
// 复杂度为O(n^2)
例子5:
js 复制代码
function print5(n) {
  for (let i = 0; i < n; i++) {
    for (let j = i; j < n; j++) {
      console.log('打印') // 打印了一次
    }
  }
}
// i = 0 -> n
// i = 1 -> n - 1
// ...
// i = n - i -> 1
// T(n) = n + (n - 1) + (n - 2) + .... + 2 + 1 = n(n + 1) / 2 = 1/2 * n^2 + 1/2*n
// 复杂度为O(n^2)
例子6:
js 复制代码
function print6(n) {
  for (let i = 0; i < n; i * 2) {
    console.log('打印') // 打印了一次
  }
}
// 假设 n = 8
// T(n) = 3 --> 2^3 = 8 --> log(2)(8) = 3(指数和对数的转换)
// 复杂度可以简单表示成 O(logn) -->(当n足够大时,可以忽略其底数,只保留其真数和对数)

可以补充一下简单的数学知识

两者可以相互转换,转换公式为a^x=N <=> log(a)(N) = x

例子7:
js 复制代码
function print(n) {
  for(let j = 0; j < n; j++) {
    for (let i = 0; i < n; i * 2) {
      console.log('打印') // 打印了一次
    }
  }
}
// 由例子6可以简单得出:
// 复杂度为O(nlog(n))

空间复杂度

空间复杂度可以简单理解成一个算法在运行过程中占用存储空间大小 的度量。通常来说,计算一个算法的空间复杂度公式为:S(n) = O(fn(n)) 其中n 为问题的规模,fn为算法所占用空间大小的函数

例子:
js 复制代码
function print(n) {
  let a = []
  const b = 1 // 是个常量 -> 1
  for(let i = 0; i < n; i++) {
    a.push(i); // a的大小随的n变而变大
  }
}
// 我们可以简单的估量程序所占用 a占用了n个空间,b暂用了一个,一共为n+1 --> O(n)
常见的几种复杂度:
  • 如果申请的是有限个数(常量)的变量(变量空间 ),空间复杂度为 O(1)
  • 如果申请的是一维数组,队列或者链表(线性空间 )等,那么空间复杂度为 O(n)
  • 如果申请的是二维数组(二维空间 ),那么空间复杂度为 O(n²)
  • 如存在递归则比较特殊(递归空间 ),空间复杂度为O(n) (递归存在时,计算机会专门分配一块空间,来存储"方法调用栈",当进入更深一层函数时,会进行入栈操作,执行完会进行出栈操作, 因此递归所需要的内存空间跟递归的深度成正比。)
  • 如果是在循环体中申请的数组等,可能就需要取嵌套的乘积来作为空间复杂度,这种就需要具体的进一步分析。
相关推荐
CoovallyAIHub6 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP7 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo7 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo8 小时前
300:最长递增子序列
算法
CoovallyAIHub13 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub13 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js