#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define MAX_RANDOM_NUM 20
/**
* 求最大子段和
* 情况1:左子段长
* 情况2:右子段长
* 情况3:右子段一部分和左子段一部分相连长
* @param arr 数组
* @param left 左下标
* @param right 右下标
* @return
*/
int maxSubNum(int *arr, int left, int right) {
int sum = 0;
if (left == right) {
sum = arr[left];
} else {
//获取左右子段的最大和
int center = (left + right) >> 1;
int leftSum = maxSubNum(arr, left, center);
int rightSum = maxSubNum(arr, center + 1, right);
//获取情况3的长度
//左子段 从右到左最大的和
int s1 = 0;
int tmpLeftSum = 0;
for (int i = center; i >= left; i--) {
tmpLeftSum += arr[i];
if (tmpLeftSum > s1) {
s1 = tmpLeftSum;
}
}
//右子段 从左到右最大的和
int s2 = 0;
int tmpRightSum = 0;
for (int i = center + 1; i <= right; i++) {
tmpRightSum += arr[i];
if (tmpRightSum > s2) {
s2 = tmpRightSum;
}
}
//情况3将两段相加获取情况3的和
sum = s1 + s2;
//判断3种情况 获取最大和
if (sum < leftSum) {
sum = leftSum;
}
if (sum < rightSum) {
sum = rightSum;
}
}
return sum;
}
//给数组进行赋值
void random(int *arr) {
//设置随机数种子
srand((unsigned int) time(NULL));
printf("生成的随机数组: ");
for(int i = 0; i < N; i++){
int num = (rand() % (MAX_RANDOM_NUM)) + 1;
//随机正负号
if (rand() % 2) {
//负数
num = -num;
}
//赋值
printf(" %d ", num);
arr[i] = num;
}
printf("\n");
}
int main() {
int *arr = (int *) malloc(N * sizeof(int));
random(arr);
printf("最大子段和: %d",maxSubNum(arr,0, N - 1));
return 0;
}
标签:arr,right,int,sum,num,小子,left
From: https://www.cnblogs.com/Liu--blog/p/18194131