对于一个连续的数组a[n],要求连续子数组,使得该子数组的和最大。比如数组{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7},最大子数组为{18,20,-7,12},和为32。
方法一:穷举法。即将任取数组中的两个元素,算出两者之间(包括这两个元素本身)所有元素之和。穷举所有组合,比较得到最大值。该方法复杂度为n的三次方。
#include
#include
int sort(int *,int,int);
main()
{
int a[16] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
printf("%d\n",sort(a,0,15));
}
int sort(int *a,int low,int high)
{
int i,j,k,sum,max_sum;
max_sum = INT_MIN;
for (i = low;i <= high;i++) {
for (j = low+1;j <= high;j++) {
sum = 0;
for (k = i;k <= j;k++) {
sum += a[k];
}
if (sum > max_sum)
max_sum = sum;
}
}
return max_sum;
}
#include
#include
int find_max_crossing_subarray(int *,int,int,int);//横跨左右数组的最大子数组
int find_maximum_subarray(int *,int,int);//返回最大子数组的和
main()
{
int a[16] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
printf("%d\n",find_maximum_subarray(a,0,15));
}
int find_max_crossing_subarray(int *a,int low,int mid,int high)
{
int left_sum = INT_MIN;
int right_sum = INT_MIN;
int sum,i;
sum = 0;//处理左数组
for (i = mid;i >= 0;i--) {
sum += a[i];
if (sum > left_sum) {
left_sum = sum;
}
}
sum = 0;//处理右数组
for (i = mid+1;i <= high;i++) {
sum += a[i];
if (sum > right_sum) {
right_sum = sum;
}
}
return left_sum + right_sum;
}
int find_maximum_subarray(int *a,int low,int high)
{
int mid;
int max_sum,max_sum1,max_sum2;
max_sum = max_sum1 = max_sum2 = INT_MIN;
if (high == low) {//元素数量为1的情况
return a[low];
} else {
mid = (low + high) / 2;
max_sum1 = find_maximum_subarray(a,low,mid);
max_sum2 = find_maximum_subarray(a,mid+1,high);
max_sum = find_max_crossing_subarray(a,low,mid,high);
if (max_sum >= max_sum1 && max_sum >= max_sum2)
return max_sum;
else if (max_sum1 >= max_sum && max_sum1 >= max_sum2)
return max_sum1;
else
return max_sum2;
}
}
#include
#include
int line_sort(int *,int,int);
main()
{
int a[16] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
printf("%d\n",line_sort(a,0,15));
}
int line_sort(int *a,int low,int high)
{
int i,sum,max_sum;
int index_start,index_end;
sum = 0;
max_sum = INT_MIN;
for (i = low;i <= high;i++) {
sum += a[i];
if (sum < 0) {
sum = 0;
index_start = i + 1;
}
if (sum > max_sum) {
max_sum = sum;
index_end = i;
}
}
if (max_sum == 0) {
max_sum = a[low];
for (i = low + 1;i <= high;i++) {
if (max_sum < a[i]) {
max_sum = a[i];
index_start = index_end = i;
}
}
}
printf("index_start:%d, index_end:%d \n",index_start,index_end);
return max_sum;
}