我是计院出身的,但是感觉自己算法方面比较薄弱,这些天抽些时间把以前的问题拿出来总结一下。最大子段和问题是一个比较基础的问题,在《数据结构与算法:c语言实现》比较靠前的位置。
为了便于说明,假设存在一个数组a,长度length.a和b做下标且a小于b。
算法一
时间复杂度:O(n^3)
算法思想:对于每一个可能的区间[a,b]都去求其和,找到其中的最大值。
int max_sub_sum_1(const int a[], int length){
int thisSum, maxSum = 0, i, j, k;
for (i = 0; i < length; i++){
for (j = 0; j < length; j++){
thisSum = 0;
for (k = i; k < j; k++){
thisSum += a[k];
}
maxSum = thisSum>maxSum ? thisSum : maxSum;
}
}
return maxSum;
}
这个算法是最简单粗暴的一种,也的确非常好理解。
算法二
时间复杂度:O(n^2)
算法思想:和上一个算法大同小异,区别是先只确定开始的下标a。
int max_sub_sum_2(const int a[],int length){
int thisSum, maxSum, i, j;
maxSum = 0;
for (i = 0; i < length; i++){
thisSum = 0;
for (j = i; j < length; j++){
thisSum += a[j];
if (thisSum>maxSum){
maxSum = thisSum;
}
}
}
return maxSum;
}
这算法其实也很好理解哒~
算法三
时间复杂度:O(n*logn)
算法简述:使用分治法策略。将这个数组一分为二,则最大子段有三种情况
- 在左半部分
- 在右半部分
- 左半部分和右半部分都有
先看看代码