𝓝𝓮𝓶𝓸&博客

【数据结构】时间复杂度

大O表示法:算法的时间复杂度通常用大O符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。

  • 大小关系:
    n→∞时,lnαn<<nβ<<an<<n!<<nn(其中α>0,β>0,a>1)

  • O(X)可以当成一个数进行运算,当所有式子运算结束后,查看数量级即可。
    n2O(1)=O(n2)4O(2k1)=2k+1

  • 等比求和公式

    Sn=a1(1qn)1q=a1anq1q

迭代程序

方程法

  • 题目:
int i=1;
while(i<=n) {
	i=i*2;
}
  • 思路:
    假设循环执行了k次,那么2k≤n,则k≤logn,所以时间复杂度为T(n)=O(logn)

求和法

  • 题目:
for(i=1; i<=n; i++)
	for(j=1; j<=i; j++)
		for(k=1; k<=j; k++)
			x++;
  • 思路:
    i=1nj=1ik=1j1=j=i(i+1)/2=O(n3)

  • 一次方(求和∑)→二次方
    二次方(求和∑)→三次方

递归程序

主方法

  • 分治法主定理:T[n] = aT[n/b] + f(n),其中n为问题规模a≥1 and b>1 是常量,并且f(n)是一个渐进正函数,也就是递归以外的计算时间,为了使用这个主定理,需要考虑下列三种情况:

    • 如果f(n)=O(nlogbaε)(即 f(n)的指数小于logba),对于某个常量ε>0成立(即 f(n)为nlogba的低阶无穷大),那么T(n)=O(nlogba)(即 时间复杂度取决于高阶无穷大

    • 如果f(n)=O(nlogba)(即 f(n)的指数等于logba)(即 f(n)为nlogba的同阶无穷大),那么T(n)=O(nlogbalogn)

    • 如果f(n)=O(nlogba+ε)(即 f(n)的指数大于logba),对于某个常量ε>0成立,并且af(n/b)≤cf(n),对于某个常量c<1(n足够大)成立(即 f(n)为nlogba的高阶无穷大),那么T(n)=O(f(n))

  • 基本步骤:

    1. a=?, b=?, f(n)=?,满足主定理条件
    2. f(n)的指数>(=)(<)logba若大于,则判断cf(n)≥a(n/b),(c<1)
    3. 故时间复杂度为O(?)

  • 题目:
    T(n)=3T(n/2)+n2
  • 思路:
    1. 试试能不能使用主方法,a=3,b=2,f(n)=n^2满足条件
    2. 看看满足哪一种情况,由于log23<2,且3n2/4<cn2(c<1),满足第三种情况,所以T(n)=O(n^2)

迭代法

  • 基本步骤:题目T(n) = aT(n/b) + f(n)

    1. 根据题目,设n=bk(这样可以消除n/b对我们判断的影响),S(k) = T(bk)(将原式子T(n)=T(bk)记为S(k)),则k=logbn,并将从S(k)到S(1)依次列出来,如:
      令 n=5k, S(k) = T(5k),则k=log5n,那么
      S(k)=6S(k1)+5k(j=0)
      S(k1)=6S(k2)+5k1(j=1)
      ...
      S(1)=6S(0)+5(j=k1)
    2. 将左端为S(k-j)的式子乘上aj之后全部加起来,即
      S(k)a0+S(k1)a1+S(k2)a2+...+S(1)ak1
      就消去了所有中间项,得到S(k)=...,如:
      S(k)=6kS(0)+[5k+65k1+...+6k15]
      =6kΘ(1)+5Θ(6k)=Θ(6k)
    3. 写成T(n)的形式,即S(k)=T(bk)=T(n)=...(其中k=logbn),如:
      k=log5n
      T(n)=Θ(nln6/ln5)
  • 题目:

//汉诺塔问题,假定move()的时间复杂度为O(1)
void hanoi(int n, char x, char y, char z) {
	if(n == 1) {
		move(x, 1, z);
	}else {
		hanoi(n-1, x, z, y);
		move(x, n, z);
		hanoi(n-1, y, x, z);
	}
}
  • 思路:
    1. 首先写出表达式:T(n) = 2T(n-1)+O(1) (即 你的问题规模分解成了2个n-1的问题规模加上执行了一次基本操作move()
    2. 试试能不能使用主方法,发现a=2,b=1,f(n)=O(1),不满足b>1的条件,不能使用
    3. 采用迭代法,因为每次迭代n的数据规模减少1,到最后必然会有终点,即n==1。

T(n)=2T(n-1)+1 T(n-1)=2T(n-2)+1 联立,得 T(n)=4T(n-2)+1+2 由数学归纳法,得 **T(n)=2^(n-1)T(1)+1+2+4+8+...+2^(n-2)** 又∵终止条件T(1)=1 ∴时间复杂度为**O(2^n)**

综合例题

一个算法所需时间由下述递归方程表示,试求出该算法的时间复杂度级别。

$$T(n)=
\begin{cases}
1& \text{n=1}\\
2T(n/2)+n& \text{n>1}
\end{cases}$$

式中,n是问题的规模,为简单起见,设n是2的整数次幂。

  • 主定理:
    a=2, b=2,f(n)=n满足条件;
    1=log22,故时间复杂度为O(nlog2n)

  • 迭代法:
    设n=2k(k≥0),则
    T(2k)=2T(2k1)+2k
    T(2k1)=2T(2k2)+2k1
    故,T(2k)=2(2T(2k2)+2k1)+2k=22T(2k2)+22k
    由归纳法,得T(2k)=2iT(2ki)+i2k
    进而i取k时,得
    T(2k)=2kT(20)+k2k
    T(n)=2log2n+log2nn=n(log2n+1)
    也就是O(nlog2n)

主定理验证作用,一般用迭代法确保满分。


求 T(n)=2T(n/4)+n^2的非递归解并证明。

  • 主定理:
    a=2,b=4,f(n)=n^2满足主定理条件;
    2>log_42,cf(n)≥2(n/4)2=n2/8,(c<1)成立;
    故时间复杂度为O(n2)

  • 迭代法:
    n=4k(k≥0),则
    T(4k)=2T(4k1)+42k
    T(4k1)=2T(4k2)+42(k1)
    故,T(4k)=2(2T(4k2)+42(k1))+42k=22T(4k2)+242(k1)+42k
    T(4k)=2iT(4ki)+2i142(ki)+...+42k
    42k为其最高阶无穷大
    i取k,得T(4k)=2kT(40)+2k140+...+42k
    limT(4k)42k = 1 = limT(n)n2
    故时间复杂度为O(n2)

某算法的时间复杂度可用递归式

$$T(n)=
\begin{cases}
O(1)& \text{n=1}\\
2T(n/2)+nlgn& \text{n>1}
\end{cases}$$
表示,若用O表示该算法的渐进时间复杂度的紧致界,则时间复杂度为?
  • 迭代法:
    1. 只考虑 n=2k 的子列, 换元之后把 T(2k) 记成 S(k), 那么
      S(k)=2S(k1)+2kk
      S(k1)=2S(k2)+2k1(k1)
      ...
      S(1)=2S(0)+2
    2. 把左端为 S(k-j) 的式子乘上 2j 之后全加起来就消去了所有中间项得到
      S(k)=2kS(0)+2k[k+(k1)+...+1]=2kO(1)+2kΘ(k2)=Θ(2kk2)
    3. 写成 T(n) 的形式就是 T(n)=Θ(n(lnn)2)
      由于 T(n) 是单调的, 考虑上述子列足够推出渐进量级了

某算法的时间复杂度可用递推式

$$T(n)=
\begin{cases}
O(1)& \text{n=1}\\
6T(n/5)+n& \text{n>1}
\end{cases}$$	
表示,则时间复杂度为?
  • 迭代法:
    1. 同样的方法, 令 n=5k, S(k) = T(5k), 那么
      S(k)=6S(k1)+5k
      S(k1)=6S(k2)+5k1
      ...
      S(1)=6S(0)+5
    2. 把左端为 S(k-j) 的式子乘上 6j 之后全加起来就消去了所有中间项得到
      S(k)=6kS(0)+[5k+65k1+...+6k15]
      =6kΘ(1)+5Θ(6k)=Θ(6k)
      注意后面那堆求和是等比数列求和
    3. 换回去就得到 T(n)=Θ(nln6/ln5)

某算法的计算时间为:T(n) = 4T(n/2) + O(n),其中 T(1) = O(1),求其时间复杂
度,写出具体过程。

设n=2k,则T(n)=T(2k)
令S(k)=T(2^k)

(1)S(k)=4kS(0)+O(2k)+4O(2k1)+...+4k1O(2)(2)=4kO(1)+2k+2k+1+...+22k1(3)=4k+4k2k(4)=O(n2)

后面一大串其实是等比数列

posted @   Nemo&  阅读(2531)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示