鱼C论坛

 找回密码
 立即注册
查看: 60|回复: 4

关于书上一个时间复杂度的问题 求大佬解决!!

[复制链接]
发表于 昨天 16:15 | 显示全部楼层 |阅读模式
30鱼币
这个是书上的练习题 老师说循环固定100次 是O(0)
但我测试下来并不是 而且当n为负数时 整个循环随n的减小而变大
n为正数是O(1)
n为负数是O(n)
所以这个代码复杂度为O(n)

测试

测试

题目

题目
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 16:17 | 显示全部楼层
关于书上一个时间复杂度的问题 求大佬解决!!
这个是书上的练习题 老师说循环固定100次 是O(0)
但我测试下来并不是 而且当n为负数时 整个循环随n的减小而变大
n为正数是O(1)
n为负数是O(n)
所以这个代码复杂度为O(n)


你好!我来帮你分析一下这个问题。

首先,时间复杂度使用大O符号表示,它描述算法运行时间随输入大小增长的速率。通常,我们考虑最坏情况,并假设输入大小n趋于无穷大。注意,O(0) 不是标准表示法,可能是个误解;常数时间应表示为 O(1)

根据你的描述,循环并不是固定100次,而是依赖于变量n。例如,如果代码类似以下形式:


  1. for i in range(n, 100):
  2.     # 循环体
复制代码


那么循环次数取决于n的值:
- 当 n < 100 时,循环次数为 100 - n
- 当 n >= 100 时,循环次数为 0

分析:
- 当n为正数时(假设n ≥ 0),循环次数最多为100次(当n=0时),因此是 O(1)
- 当n为负数时,随着n减小(如n=-100、-1000),循环次数100 - n会增大,与 |n| 成正比,因此是 O(n)(因为大O关心增长率,|n| 和 n 同阶)。

整体时间复杂度取最坏情况:当n趋于负无穷时,循环次数无界,所以是 O(n)

你的分析是正确的!老师可能误将固定循环说成了 O(0),但实际由于n影响循环次数,复杂度为 O(n)。如果n通常为非负,可视为 O(1),但根据你的测试,需考虑所有输入。

希望这能帮到你!如果提供具体代码,我可以更精确分析。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 昨天 16:21 | 显示全部楼层
这个是书上的练习题 老师说循环固定100次 是O(1) 打错字了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 16:22 | 显示全部楼层
1921137080 发表于 2025-09-26 16:21
这个是书上的练习题 老师说循环固定100次 是O(1) 打 ...


你好!感谢澄清,老师说的是 O(1),这确实是一个常见的理解点。我来帮你分析一下。

首先,如果循环确实是固定 100 次(比如 `for i in range(100):`),那么时间复杂度是 O(1),因为循环次数不随输入变化。

但根据你的描述,代码可能类似于:


  1. for i in range(n, 100):
  2.     # 循环体
复制代码


这里,循环次数取决于 n 的值:
- 当 n < 100 时,循环次数为 100 - n
- 当 n >= 100 时,循环次数为 0

在时间复杂度分析中,我们通常考虑最坏情况,并且假设输入规模 n 可以取任意值(包括负数)。因此:
- 当 n 为负数时,随着 n 减小(如 n = -100, -1000),循环次数 100 - n 会无限增长,与 |n| 成正比,所以是 O(n)。
- 当 n 为非负数时,循环次数最多为 100 次(当 n=0 时),所以是 O(1)。

整体来看,如果 n 可以是任意整数,那么最坏情况(n 趋于负无穷)下,时间复杂度是 O(n)。你的测试结果正确!

然而,许多教科书问题中,n 被默认视为非负整数(如输入大小)。如果练习题有这种假设,那么老师说的 O(1) 是合理的,因为 n 通常不会为负。

建议检查一下问题描述,看是否有对 n 范围的限制。如果没有明确说明,你的 O(n) 分析更全面。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 18:15 | 显示全部楼层
老师那句“循环固定100次”只在 n>100 时才成立;

当 n≤100 时,循环次数会随 n 变大而线性增长。

先把代码复原成逻辑:

  1. void fun(int n){
  2.     int x = n, y = 100;
  3.     while (y > 0){
  4.         if (x > 100){
  5.             x -= 10;
  6.             y--;
  7.         }else{
  8.             x++;      // 注意:此分支不减少 y
  9.         }
  10.     }
  11. }
复制代码


精确步数(以循环次数计)

若 n>100:每次都走 if 分支,y 每轮减1,共 100 次,与 n 无关 &#8658; 常数次。

若 n≤100:先要把 x 从 n 增到 101,需 (101&#8722;n) 次(全是 else,不减 y)。
之后每“消耗一次 y”要经历:10次 else(把 x 从91涨回101)+1次 if,即 11 次。

从 y=100 减到 0 需要 100 次 if,中间夹着 99 组“10 次 else”。

因此总次数:

  1. T(n)=(101&#8722;n)+100+99×10=1191&#8722;n
复制代码

验证:n=0&#8658;T=1191,与你的实测一致;n=&#8722;99999&#8658;T=101190。

复杂度结论:

  • n>100:T(n)=Θ(1)
  • n≤100:T(n)=Θ(101&#8722;n)=Θ(&#8722;n)(当 n→&#8722;∞ 时线性增长)
  • 最坏情况复杂度:Θ(∣n∣)(更精确地说是 Θ(max{1,101&#8722;n}))

老师说的 O(1) 只在默认 输入满足 n>100(或仅关注 if 支路)时成立;对一般 n 而言,上面这份分段与“最坏为线性”才是准确结论。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-9-27 06:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表