分治法--最大子数组

算法导论分治算法

分治法:将数组尽可能分成规模相等的两部分,所以最大子数组无外乎三种情况

1.全在左数组a[low->mid]中

2.全在右数组a[mid+1->high]中

3.在左右中a[mid-i->mid+j]中

所以我们将问题进行细化,接下来的内容在代码中进行讲解

下面这道题的答案是43

#include"iostream"
#include"cstdio"
#define inf -99999999           //对求左右中间的数组中为左边最大和 和 右边最大和进行初始化,保证正确计算(因为要进行比较)

using namespace std;


int maxsubcross(int a[],int low,int mid,int high)                     //maxsubcross和maxsub函数小心返回值是整数(最大的子数组的和值)
{
int leftsum=inf;
int rightsum=inf;
int sum=0;
for(int i=mid;i>=low;i--)
{
sum+=a[i];
if(sum>=leftsum)
{
leftsum=sum;
}
}
sum=0;
for(int i=mid+1;i<=high;i++)
{
sum+=a[i];
if(sum>=rightsum)
{
rightsum=sum;
}
}
return leftsum+rightsum; 
}


int maxsub(int a[],int low,int high)
{
int leftsum;
int rightsum;
int crosssum;
int mid=(low+high)/2;
if(low==high)                  //当无法再二分的时候,返回当前这个值就好(这个值最大)
{
return a[low];
}
else
{
leftsum=maxsub(a,low,mid);                      //目的是递归到底
rightsum=maxsub(a,mid+1,high);                  //目的是递归到底
crosssum=maxsubcross(a,low,mid,high);       //目的是递归到底
if(leftsum>=rightsum&&leftsum>=crosssum)
{
return leftsum;
}
else
{
if(rightsum>=leftsum&&rightsum>=crosssum)
{
return rightsum;
}
else        //leftsum和rightsum都不是最大的,那么就只有crosssum是最大的了
{
return crosssum;
}
}
}
}


int main()
{
int a[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
int length=sizeof(a)/sizeof(int);
cout<<maxsub(a,0,length-1)<<endl;
return 0;
}



深度思考1:

如果不仅要返回最大子数组的和,还要其初始位置和终止位置

添加全局变量每次更新进行记录就好


深度思考2:

如果不仅要返回最大子数组的和,还要其全部子数列的成员

添加全局数组,每次更新记录就好

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值