《数据结构》详解精炼:时间复杂度(3)

第 2 章 算法分析

2.8 时间复杂度(4)

1. 一个较复杂的问题

例题 2.8.1 估算以下算法的时间复杂度:

c 复制代码
void fun(int n){
    int x = 0;
    for(int i = 0, j = 0; i < n; i += j, j++)
        x++;
}

在循环语句中,i, j 都是从 0 开始,j 的步长是 1,但 i 的步长是 j 。通过下表,观察在迭代过程中两个变量的变化(注意,先执行 i += j )。

循环次序 i(i+=j) j(j++)
1 0+0 1
2 0+0+1 2
3 0+0+1+2 3
4 0+0+1+2+3 4
⋮ \vdots ⋮ \vdots ⋮ \vdots
r 0 + 0 + 1 + 2 + 3 + ⋯ + ( r − 1 ) 0+0+1+2+3+\cdots+(r-1) 0+0+1+2+3+⋯+(r−1) r

因为 i < n ,所以: 0 + 0 + 1 + 2 + 3 + ⋯ + ( r − 1 ) < n 0+0+1+2+3+\cdots+(r-1)\lt n 0+0+1+2+3+⋯+(r−1)<n ,即:
r ( r − 1 ) 2 < n r 2 − r − 2 n < 0 1 − 1 + 8 n 2 < r < 1 + 1 + 8 n 2 ∵ r > 0 ∴ 0 < r < 1 + 1 + 8 n 2 \begin{split} &\frac{r(r-1)}{2}\lt n \\&r^2-r-2n\lt0 \\&\frac{1-\sqrt{1+8n}}{2}\lt r\lt\frac{1+\sqrt{1+8n}}{2} \\&\because~r\gt0 \\&\therefore~0\lt r\lt\frac{1+\sqrt{1+8n}}{2} \end{split} 2r(r−1)<nr2−r−2n<021−1+8n <r<21+1+8n ∵ r>0∴ 0<r<21+1+8n

所以,时间复杂度为 O ( n ) O(\sqrt{n}) O(n ) 。

2. 多项式时间复杂度

至此,已经学习过的时间复杂度包括: O ( 1 ) , O ( log ⁡ n ) , O ( n ) , O ( n ) , O ( n log ⁡ n ) , O ( n 2 ) , O ( n 3 ) O(1),O(\log{n}),O(\sqrt{n}),O(n),O(n\log{n}),O(n^2),O(n^3) O(1),O(logn),O(n ),O(n),O(nlogn),O(n2),O(n3) ,在 013 节的练习题中还有 O ( log ⁡ log ⁡ n ) O(\log\log{n}) O(loglogn) 。这些时间复杂度之间,存在如下定性的大小关系:
O ( 1 ) < O ( log ⁡ log ⁡ n ) < O ( log ⁡ n ) < O ( n ) < O ( n ) < O ( n log ⁡ n ) < O ( n 2 ) < O ( n 3 ) O(1)\lt O(\log\log{n})\lt O(\log{n})\lt O(\sqrt{n})\lt O(n)\lt O(n\log{n})\lt O(n^2)\lt O(n^3) O(1)<O(loglogn)<O(logn)<O(n )<O(n)<O(nlogn)<O(n2)<O(n3)

其中, O ( log ⁡ log ⁡ n ) , O ( log ⁡ n ) , O ( n ) , O ( n ) , O ( n log ⁡ n ) , O ( n 2 ) , O ( n 3 ) O(\log\log{n}), O(\log{n}), O(\sqrt{n}), O(n), O(n\log{n}), O(n^2), O(n^3) O(loglogn),O(logn),O(n ),O(n),O(nlogn),O(n2),O(n3) 等称为多项式时间复杂度 (polynomial time complexity),可以统一表示为 O ( f ( n ) ) O(f(n)) O(f(n)) ,且 f ( n ) f(n) f(n) 为多项式。

在算法复杂度理论中,多项式级的运行时间成本,往往被认为是可接受的,或者是可忍受的。某问题若可以用多项式复杂度的算法求解,则称该问题是可有效求解的,或者易解的。这样的问题也称为 P 问题。

除了 P 问题之外,也就是解决问题的算法的复杂度是多项式复杂度,除此之外,还有另外一类问题,只能用指数时间复杂度的算法求解,称为 NP 问题,或者称为难解问题。

3. 指数时间复杂度 O ( 2 n ) O(2^n) O(2n)

指数时间复杂度不是本课程重点,但是,考虑到学习本课的同学,将来的学习、工作或者研究过程中,一定不会仅仅局限于教材或者所谓考研大纲的知识范围,那么,也对此做个简单介绍。

例题 2.8.3 n n n 是非负整数,计算 2 n 2^n 2n ,其算法如下(注意,这里的算法是此计算的一种,蛮力迭代,并不是最好的算法,此处仅仅是以此为例说明指数时间复杂度)。

c 复制代码
int power(int n){
    int pow = 1;
    while(0 < n--){
        pow <<= 1;  // pow = pow * 2
    }
    return  pow;
}

很显然,第 4 行是基本语句,语句频度是 n n n ,所以此算法的时间复杂度为 O ( n ) O(n) O(n) 。

如果将输入指数 n n n 用二进制位数 r = 1 + ⌊ log ⁡ n ⌋ r = 1+\lfloor\log{n}\rfloor r=1+⌊logn⌋ 作为输入规模,则时间复杂度为 O ( 2 r ) O(2^r) O(2r) 。

把时间复杂度可以表示为 T ( n ) = O ( a n ) , ( a > 1 ) T(n)=O(a^n),(a\gt1) T(n)=O(an),(a>1) 的,均是指数时间复杂度(exponential time complexity)。

一般认为,指数时间复杂度的算法无法真正应用于实际问题中,这类算法不是有效的算法。

本文由mdnice多平台发布

相关推荐
demo007x9 小时前
让大模型活在你的鼠标旁:我用 Tauri 2 + Rust 打造了一款“反直觉”的 AI 全局划词效率神器
macos·程序员·llm
程序员海军10 小时前
AI 越来越强,为什么打工人反而越来越累、越来越内耗了?
前端·程序员·aigc
badhope15 小时前
同样写 AI,为什么有的文章 549 人看、有的只有 16 人看?——我用 40 篇掘金文章的真实数据复盘
程序员
今朝唯我少年郎2 天前
Codex安全盲区代码漏洞生成实测
python·程序员
kyriewen2 天前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
酷酷的逗逗乐2 天前
前端转 Agent 开发 · 第六节
前端·程序员
爱勇宝2 天前
没有 Fn 键关触控板?我做了一个双击即用的 Windows 小工具
前端·后端·程序员
程序员cxuan3 天前
跟 WebUI 说再见了,最强 DeepSeek 桌面端来了!
人工智能·后端·程序员
codigger3 天前
用 AI 写代码,你知道它会把我的代码传去哪?
ai·程序员·编程·数据安全
程序员cxuan3 天前
DeepSeek V4.1 Flash 正式发布!
人工智能·后端·程序员