目录
一.算法
广义上讲,算法就是指“达成某种目的的步骤”。
在计算机界,我们将通过数据处理,数值运算,组合运算,模拟等操作解决问题的步骤成为算法。
伪代码:描述算法的方式之一,将自然语言和编程语言相结合的的一种算法描述语言。
二.复杂度
1.复杂度的评估。
算法的效率主要有时间复杂度和空间复杂度来评估。
- 时间复杂度:评估程序所需要的时间。
- 空间复杂度:评估程序所需要的存储空间。
时间复杂度往往比空间复杂度更容易出问题。没有特别说明,“复杂度”指“时间复杂度”。
2.复杂度的比较。
在大O表示法中用O(n),O()的形式来表示算法的效率,其中n为问题输入数据的大小。
O(g(n))代表该算法的复杂度与g(n)成正比(暂时这样理解),也称该算法是g(n)级的。
假设一个算法的数量级为O(),即a的复杂度与成长正比,当n增加10倍时,复杂度增加100倍。
n | logn | nlogn | n! | |||
5 | 2 | 2 | 10 | 25 | 32 | 120 |
10 | 3 | 3 | 30 | 100 | 1024 | 3628800 |
20 | 4 | 4 | 80 | 400 | 1048576 | |
50 | 5 | 7 | 250 | 2500 | ||
100 | 6 | 10 | 600 | 10000 |
数量级为O(),O(logn),O(nlogn)时,随n的增加,复杂度增加不是很多,数量级为O(),O(),O(n!)时,有大幅度的增加。
三.举例
例题
现有n个数字,计算出(>)的最大值。
输入:第一行输入数字n,第二行输入分别输入n个数字。
输出:在下一行输出最大值。
限制:
分析
让人最先想到的是对i,j分别进行内外循环,比较差值的大小,输出最大值。
for (j = 1; j < n; j++) {
for (i = 0; i < j; i++) {
max = MAX(max, a[j] - a[i]);
}
}
虽然此算法可以算出正确答案,但是算法复杂度为O(),结合n的范围,可以知道此算法不够高效,需要用其他算法解决问题。
我们可以在j自增的过程中,把最小值保存下来,用当前减去最小值,然后再和最大差值比较,得出更大的差值。
int min=a[0],max=a[1]-a[0];
for (int j = 1; j < n; j++) {
max = MAX(max, a[j]-min);//不能交换这两行代码
min = MIN(min, a[j]);
}
此算法复杂度为O(n),极大减少了运行时间,提高了程序的效率。同时此算法还可以省略数组,不用将数据保存到数组中,改善了内存使用量。
完整代码如下:
#include<stdio.h>
#define MAX_N 200000
int MAX(int x,int y) {
return x > y ? x : y;
}
int MIN(int x, int y) {
return x > y ? y : x;
}
int main() {
int n,a[MAX_N];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int min=a[0],max=a[1]-a[0];
for (int j = 1; j < n; j++) {//可以省略数组
max = MAX(max, a[j]-min);
min = MIN(min, a[j]);
}
printf("%d", max);
return 0;
}
四.总结
使用合适的算法可以极大地减少运行时间,降低复杂度。
学习算法知识,可以提升我们的编程能力,让我们的语言更加简洁,高效,更好地解决问题。
读《挑战程序设计竞赛》第一天 (侵删) 2021.2.19
( 2021.7.5 第一次修改)