1. 分治策略:
数组a(长度为n)的最大子数组为:
1. a[0]到a[n/2]的最大子数组;
2. a[n/2+1]到a[n-1]的最大子数组;
3. a[i]到a[j],其中i <= n/2 <= j;
定义一个结构体承载返回结果:
typedef struct max_sub_array{
int low;
int high;
int sum;
max_sub_array(int l, int h, int s) {
low = l;
high = h;
sum = s;
}
}max_sub_array;
包含中间值的最大子数组:
max_sub_array FindMaxCrossingSubArray(int* a, int low, int mid, int high) {
int leftsum = -MAXN;
int rightsum = -MAXN;
int sum = 0;
int max_left, max_right;
max_left = max_right = mid;
for (int i = mid; i >= low; i--) {
sum = sum + a[i];
if (sum > leftsum) {
leftsum = sum;
max_left = i;
}
}
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum = sum + a[i];
if (sum > rightsum) {
rightsum = sum;
max_right = i;
}
}
max_sub_array ans(max_left, max_right, leftsum + rightsum);
return ans;
}
最终的函数:
max_sub_array FindMaxSubArray(int* a, int low, int high) {
if (high == low) {
return max_sub_array(low, high, a[low]);
} else {
int mid = (low + high) / 2;
max_sub_array left = FindMaxSubArray(a, low, mid);
max_sub_array right = FindMaxSubArray(a, mid + 1, high);
max_sub_array cross = FindMaxCrossingSubArray(a, low, mid, high);
if (left.sum >= right.sum && left.sum > cross.sum) {
return left;
} else if (right.sum >= left.sum && right.sum > cross.sum) {
return right;
} else {
return cross;
}
}
}
2.线性时间解法:
其实我不觉得是线性时间,但是确实可以优化很多,思路就是当数组向后扩展的时候,我先假设我得到当前数组的最大子数组,然后判断如果新增加一个元素,是否能构成新的最大子数组。
max_sub_array LinearSolution(int* a, int low, int high) {
if (high == low) {
return max_sub_array(low, high, a[low]);
} else {
max_sub_array temp(low, low, a[0]);
for (int i = low + 1; i <= high; i ++) {
if (a[i] > 0) {
int max = a[i];
int j = i - 1;
int low_ = temp.low;
while(j >= low_) {
max = max + a[j];
if (max > temp.sum) {
temp.low = j;
temp.high = i;
temp.sum = max;
}
j--;
}
}
}
return temp;
}