数据结构
定义
抽象数据类型
类似于java中的类的概念
算法
定义
- 一个指令集 每条指令都不能有歧义
- 产生输出
- 在有限步骤之后终止
评判标准
往往看的是最差的情况
- 时间复杂度T(n)
- 空间复杂度S(n)
上界:O(f(n))
下界:Ω(g(n))
C⋅g(n)≤T(n)≤C⋅f(n)
习题
最大子列和问题
给定n个整数的序列,求其中子列和的最大值。
如{-2,11,-4,13,-5,-2}其连续子列{11,-4,13}有最大的和20
暴力算法
T(N)=O(N³)
int MaxSubseqSum1(int n, int a[]) {
int max = 0;
for (int i = 0; i < n; i++) {//i是子列左端
for (int j = i; j < n; j++) {//j是子列右端
int tmp = 0;//用于储存子列和的临时变量
for (int k = i; k <= j; k++) {//从i加到j 如果比max大则替换max
tmp += a[k];
if (tmp > max) {
max = tmp;
}
}
}
}
return max;
}
较暴力算法
T(N)=O(N²)
int MaxSubseqSum2(int n, int a[]) {
int max = 0;
for (int i = 0; i < n; i++) {//i是子列左端
int tmp = 0;//用于储存子列和的临时变量
for (int j = i; j < n; j++) {//j是子列右端
tmp += a[j];//i同j不同时 只需在j-1后加上最后一项
if (tmp > max) {
max = tmp;
}
}
}
return max;
}
分治算法
把整个数列一分为二,再一分为二,一直递归直到每个小序列左右两边只有一个数字;判断左边大还是右边大还是中间大,求出小序列的最大子列和;最后再递归回去,求出整个大序列的最大子列和
课程中仅讲解了分治算法思想 没有展示具体代码
贪心算法
从左到右遍历数组,如果前面的和加上当前值是负数(意味着对之后的加和没有帮助),就抛弃前面的数字们,如果如果前面的和加上当前值比max还大,就更新max
T(N)=O(N)
int MaxSunseqSum4(int n, int a[]) {
int max = 0;
int tmp = 0;
for (int i = 0; i < n; i++) {//向右累加
tmp += a[i];
if (tmp > max) {//发现更大的和则更新结果
max = tmp;
}
else if (tmp < 0) {//如果当前子列和为负 则不可能使后面的部分和更大 全部抛弃
tmp = 0;
}
}
return max;
}