欢迎光临
我们一直在努力

GESP5级C++考试语法知识(三、时间与空间复杂度的估算)

故事前言:

🌟《算法王国的速度比赛》

1、在 算法王国里,每年都会举行一次 程序速度大赛。

参赛的不是人,而是各种 算法机器人 🤖。


2、比赛规则很简单:

给机器人很多很多数据,看谁完成任务最快。


3、但是评委发现一个问题:

  • 如果数据只有 10个,几乎所有算法都很快

  • 如果数据有 100万,有些算法就慢得像乌龟 🐢


4、于是评委们发明了一种评估标准:

🧠 算法复杂度


5、用来估算:

  • 时间复杂度 ⏰
    程序大约要做多少次计算

  • 空间复杂度 📦
    程序需要多少内存


6、今天我们主要学 时间复杂度估算。


一、算法复杂度的核心思想

1、记住一句最重要的话:

只看数据规模 n 变大时,程序增长的速度


2、比如:

数据量:

n = 10
n = 100
n = 1000
n = 100000


3、我们关心的是:

程序运行次数怎么变。


二、最常见的复杂度

1、算法王国有几个著名选手:

复杂度名字速度
O(1) 常数算法 🚀最快
O(log n) 对数算法 很快
O(n) 线性算法 正常
O(n log n) 稍慢
O(n²) 平方算法
O(n³) 立方算法 非常慢

2、记住顺序:

O(1) < O(log n) < O(n) < O(n log n) < O(n²)< O(n³)


三、第一种:O(1) 常数复杂度

1、故事:

机器人只做 一次操作。


2、比如:

int n ;
cin >> n;
cout << n++;


3、无论:

n = 10
n = 1000
n = 100000


4、操作次数都是:

cin 操作 1次
cout 操作 1次
n++ 操作 1次

一共3次


5、所以:

时间复杂度 = O(1)


6、意思是:

操作次数是固定的常数。


四、第二种:O(n) 线性复杂度

1、故事:

机器人要检查 每一个箱子。


2、如果有 n 个箱子。

程序:

for(int i=1;i<=n;i++)
{
cout<<i<<endl;
}


3、算一算:

(1)如果:n = 5

         循环:

5次


(2)如果:n = 100

          循环

100次


(3)操作次数:

≈ n


4、所以:

时间复杂度 O(n)


五、第三种:O(n²) 平方复杂度

1、故事:

学校要让 每个学生和所有学生握手 🤝


2、程序:

for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<i<<" "<<j<<endl;
}
}


3、算一算:

(1)如果

n = 5

次数

5 × 5 = 25


(2)如果

n = 100

次数

100 × 100 = 10000


4、所以:

时间复杂度 O(n²)


5、口诀:

两层循环 → n²
三层循环 → n³


六、含多项式的复杂度

1、有时候程序不是简单循环。


2、例如:

for(int i=1;i<=n;i++)
{
cout<<i<<endl;
}

for(int i=1;i<=n*n;i++)
{
cout<<i<<endl;
}


第一部分:

n 次


第二部分:

n² 次


总次数:

n + n²


3、复杂度写作:

O(n + n²)


4、但在复杂度估算里:

只保留 最大项


5、所以:

时间复杂度:O(n²)


6、口诀:

多项式只看最大项


7、例子:

原公式复杂度
n² + n O(n²)
n³ + n² + n O(n³)
5n² + 3n O(n²)

8、原因:

当 n 很大时:

n² 远大于 n


七、对数复杂度 O(log n)

这是很多学生不容易理解的。

我们用故事讲。


1、故事:猜数字游戏

(1)老师想一个数:

1 ~ 100


(2)你每次猜。

老师说:

大了
小了


(3)聪明的方法是:

每次猜中间。


(4)例如:

第一次

猜 50

范围变成

50 ~ 100


第二次

猜 75

范围变

75 ~ 100


第三次、第四次…….

范围越来越小。


(5)每次:

数据量减半

这就是:

log₂ n


(6)例如:

log₂8 = 3


2、所以对数复杂度是:

O(log n)


八、经典例子:二分查找

while(l <= r)
{
mid = (l+r)/2;

if(a[mid]==x)
return mid;

if(a[mid] < x)
l = mid+1;
else
r = mid-1;
}

每次:

范围减半

所以:

时间复杂度 O(log n)


九、组合复杂度

1、有时复杂度会组合。


2、例如:

for(int i=1;i<=n;i++)
{
int l=1,r=n;

while(l<=r)
{
int mid=(l+r)/2;
}
}


(1)外层:

n 次


(2)内层:

log n


(3)总复杂度:

n × log n


(4)所以:

O(n log n)


十、空间复杂度

1、空间复杂度 = 使用的内存。


2、例如:

(1)一维数组:

int a[100000];


(2)需要

100000 个空间


(3)所以:

空间复杂度 O(n)


(4)如果是二维数组:

int a[n][n];


(5)需要N*N个空间:

空间复杂度 O(n²)


(6)如果只是:

int a,b,c;


(7)只有固定变量:

O(1)


十一、复杂度估算三步法

学生推荐用下列方法:


1、第一步:找到循环

看有几层循环。

1层 → n
2层 → n²
3层 → n³


2、第二步:看循环范围

(1)例如:

for(i=1;i<=n;i++)

是:

n


(2)如果:

i *= 2

就是:

log n


3、第三步:合并复杂度

例如:

n + n² → n²
n × log n → n log n


十二、给学生的记忆口诀

一层循环 O(n)

两层循环 O(n²)

三层循环 O(n³)

每次减半 O(log n)

循环+二分 O(n log n)

多项式只看最大项


十三、练习题(判断复杂度)

题1

for(int i=1;i<=n;i++)
cout<<i;

答案

O(n)


题2

for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cout<<i*j;

答案

O(n²)


题3

for(int i=1;i<=n;i*=2)
cout<<i;

答案

O(log n)


题4

for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cout<<j;

次数:

1+2+3+…+n

n²/2

复杂度

O(n²)


十四、算法竞赛经验

如果

一般:

复杂度是否可行
O(n)
O(n log n)
O(n²)

所以竞赛里:

n ≤ 10^5 → 需要 O(n log n)


🌟最后一句话

算法复杂度不是精确时间,而是增长速度。

我们关心的是:

n变大时
程序变慢多少


赞(0)
未经允许不得转载:171主机测评 » GESP5级C++考试语法知识(三、时间与空间复杂度的估算)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址