最大子数组问题

问题描述:子数组为数组中连续的一段序列,求最大子数组指的是找到一个非空子数组,使得它的序列和最大。即给定一个数组a[n],对于任意一对数组小标 l,r(l<=r)的非空子数组,其和记为S(l,r)=a[l]+…a[r],求出S(l,r)的最大值。
输入
第一行输入一个整数n,第二行输入n个整数,在这n个整数中找到最大子数组

输出
输出一个整数,即S(l,r)的最大值

解题思路
如果用蛮力枚举的话,要枚举 n + C n 2 . n+C_n^2. n+Cn2.
种下标 l,r组合,再求出最大子数组之和

int max=0;
for(int i=1;i<=n;i++) //这里数组a[0]不存数据
{ int s=0;
  for(int j=i;j<=n;j++){
     s+=a[j];
     if(max<s) max=s;
   }
}
printf("%d\n",max);  

用分治策略则将数组二分,然后递归求解两个子数组的最大子数组,得到S1,S2,再合并子问题得到S_max,关键在于求跨中点的最大子数组S3,S_max=max{S1,S2,S3}
mid=n/2,S3求和时一定包括a[mid],a[mid+1],则S3可以分为两部分的和,以a[mid]结尾的最大子数组之和,以a[mid+1]开头的最大子数组之和
参考下列代码:

int max(int a,int b,int c);
int CrossingSubArray(int a[],int left,int mid,int right);
int MaxSubArray(int a[],int left,int right){
if(left>=right) return 0;
else{
    int S1,S2,S3;
    int mid=(left+right)/2;
   S1=MaxSubArray(a,left,mid);
   S2=MaxSubArray(a,mid+1,right);
   S3=CrossingSubArray(a,left,mid,right);
  return max(S1,S2,S3);
  }
}
int CrossingSubArray(int a[],int left,int mid,int right){
  int L=0,SL=0;
  for(int i=mid;i>=left;i--) //数组下标为0的位置不存数据    
  {    SL+=a[i];
      if(SL>L) L=SL;  }
  int R=0,SR=0;
  for(int i=mid+1;i<=right;i++){
   SR+=a[i];    if(SR>R) R=SR;
   }
  return L+R;
}
int max(int a,int b,int c){
a=a>b?a:b;
return a>c?a:c;
}

蛮力枚举的时间复杂度为O(n^2)
分而治之的时间复杂度为O(nlogn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yun_gao_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值