最大子数组(分治策略)C++
思路:求一个数组的最大子数组可将其看为求其左子数组和右子数组以及跨越中间的子数组三者中的最大值。
跨越中点情况:
int findMaxCrossingSubarray(int a[], int low, int mid, int high) {
int leftsum = INT_MIN;
//int maxleft;//下标
int sum = 0;
for (int i = mid; i >= low; i--) {
sum += a[i];
if (sum > leftsum) {
leftsum = sum;
//maxleft = i;
}
}
int rightsum = INT_MIN;
//int maxright;//下标
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if (sum > rightsum){
rightsum = sum;
//maxright = i;
}
}
return leftsum + rightsum;
}
int findMaxSubarray(int a[], int low, int high) {
if (low == high)
return (low, high, a[low]);
else {
int mid = (low + high) / 2;
int leftsum = findMaxSubarray(a, low, mid);
int rightsum = findMaxSubarray(a, mid + 1, high);
int crosingsum = findMaxCrossingSubarray(a, low, mid, high);
return max(leftsum,max( rightsum, crosingsum));
}
}
总测试代码:
#include<iostream>
#include<limits.h>
#include<algorithm>
using namespace std;
int findMaxCrossingSubarray(int a[], int low, int mid, int high) {
int leftsum = INT_MIN;
//int maxleft;//下标
int sum = 0;
for (int i = mid; i >= low; i--) {
sum += a[i];
if (sum > leftsum) {
leftsum = sum;
//maxleft = i;
}
}
int rightsum = INT_MIN;
//int maxright;//下标
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if (sum > rightsum){
rightsum = sum;
//maxright = i;
}
}
return leftsum + rightsum;
}
int findMaxSubarray(int a[], int low, int high) {
if (low == high)
return (low, high, a[low]);
else {
int mid = (low + high) / 2;
int leftsum = findMaxSubarray(a, low, mid);
int rightsum = findMaxSubarray(a, mid + 1, high);
int crosingsum = findMaxCrossingSubarray(a, low, mid, high);
return max(leftsum,max( rightsum, crosingsum));
}
}
int main() {
int a[10] = { 2,-3,5,-7,4,3,-1,8,3,-2 };
cout << findMaxSubarray(a, 0, 9);
}
说明:INT_MIN是<limits.h>定义的一个宏,代表无穷小啊