求一个序列中的子序列和的最大值
#include <stdio.h>
/* 求 给定含有 0 一个序列中 子序列和 的最大值 */
int n = 0;
int main() {
int maxOne(int a[]);
int maxTwo(int a[], int left, int right);
int maxThree(int a[]);
int max(int a, int b, int c);
printf("请输入你想数组的个数:");
scanf("%d", &n);
int a[n];
printf("\n请输入数组:\n");
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for(int i = 0; i < n; i++) {
printf("%d\n", a[i]);
}
//算 int 数组的长度,不用理会
printf("%d\n\n", sizeof(a) / sizeof(int));
int one = maxOne(a);
int two = maxTwo(a, 1, n);
int three = maxThree(a);
printf("for 循环运行的结果:%d\n", one);
printf("分而治之运行的结果:%d\n", two);
printf("在线处理运行的结果:%d\n\n", three);
}
/* for 循环 */
int maxOne(int a[]) {
int thisSum, maxSum = 0;
for(int i = 0; i < n; i++) {
thisSum = 0;
for(int j = i; j < n; j++) {
thisSum += a[j];
if(thisSum > maxSum) {
maxSum = thisSum;
}
}
}
return maxSum;
}
/* 分而治之 */
int max(int a, int b, int c) {
return a >= b ? a >= c ? a : c : b >= c ? b : c;
}
int maxTwo(int a[], int left, int right) {
/* 分治法求 */
int maxLeftSum, maxRightSum; /* 存放左右子问题的解 */
int maxLeftBorderSum, maxRightBorderSum; /*存放跨分界线的结果*/
int leftBorderSum, rightBorderSum;
int center, i;
/* 递归的终止条件,子列只有1个数字 */
if(left == right) {
if(a[left - 1] > 0) {
return a[left - 1];
} else {
return 0;
}
}
/* 下面是"分"的过程 */
center = (left + right) / 2;
/* 递归求得两边子列的最大和 */
maxLeftSum = maxTwo(a, left, center);
maxRightSum = maxTwo(a, center + 1, right);
/* 下面求跨分界线的最大子列和 */
maxLeftBorderSum = 0; leftBorderSum = 0;
/* 从中线向左扫描 */
for(i = center - 1; i >= left - 1; i--) {
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
} /* 左边扫描结束 */
maxRightBorderSum = 0; rightBorderSum = 0;
/* 从中线向右扫描 */
for(i = center; i < right; i++) {
rightBorderSum += a[i];
if( rightBorderSum > maxRightBorderSum )
maxRightBorderSum = rightBorderSum;
} /* 右边扫描结束 */
/* 下面返回"治"的结果 */
return max(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
/* 在线处理 */
int maxThree(int a[]) {
int thisSum = 0, maxSum = 0;
for(int i = 0; i < n; i++) {
thisSum += a[i];
if(thisSum > maxSum) {
maxSum = thisSum;
} else if(thisSum < 0) {
thisSum = 0;
}
}
return maxSum;
}
结果
这三种方法的时间复杂度:
(1) n 的平方
(2) n 乘以 log n
(3) n