最大子数组

来源:互联网 发布:港融大数据平台 编辑:程序博客网 时间:2024/06/16 02:10

题目描述

给出一个数组A[0..n-1],求数组A中和最大的连续子数组。

输入描述

第1行为一个整数N(N>0),表示数组元素个数。
第2行为数组的N个元素,每个元素为整数,相互之间用空格分隔。

输出描述

在一行中输出最大子数组的起始下标、结束下标和子数组的和,用空格分开。

输入样例

1613 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7

输出样例

7 10 43

提示

来源or类型

思路:第一种方法:暴力求解,不知道能不能过因为我没有尝试;
           第二种方法:分治法:
               
#include<iostream>#include<cstdlib>#include<cstdio>#include<limits.h>using namespace std;struct XB              //使用结构体输出;由于return 不能同时返回三个值;{    int left;    int right;    int value;};XB cross_middle(int *a,int l,int m,int r)    //分治法是分成了三种情况,这就是最复杂的一种---跨越左半部分和右半部分{    XB p;    int i;    int sum=0;    int l_max=-999999;    int r_max=-999999;    for(i=m;i>=1;i--)    {         sum+=a[i];        if(sum>l_max)        {                 l_max=sum;                 p.left=i;        }    }    sum=0;    for(i=m+1;i<=r;i++)    {        sum+=a[i];        if(sum>r_max)        {              r_max=sum;              p.right=i;        }    }    p.value=l_max+r_max;    return p;}XB maxsubset(int *a,int l,int r)        //函数要定义为结构体形式的函数;{    XB p;    if(l==r)                             //一个元素的情况;    {        p.left=l;        p.right=r;        p.value=a[l];        return p;    }   int m=(l+r)/2;                        //开始进行分治;   XB l_max=maxsubset(a,l,m);   XB r_max=maxsubset(a,m+1,r);   XB c_max=cross_middle(a,l,m,r);    if(l_max.value>=r_max.value&&l_max.value>=c_max.value)        p=l_max;    else if(r_max.value >= l_max.value&&r_max.value >= c_max.value)        p=r_max;    else        p=c_max;        return p;                        //这样返回值就可以返回了多值,从而满足了题意;}int main(){    int a[10010];    XB p;    int N;    cin>>N;    for(int i=0;i<N;i++)                           scanf("%d",&a[i]);    p=maxsubset(a,0,N-1);    printf("%d %d %d\n",p.left,p.right,p.value);    return 0;}
            第三种方法:线性时间解决问题,也是最单的一种方法
       
#include<iostream>#include<cstdio>using namespace std;int a[100010];int main(){    int N;    int flag=0;    cin>>N;    int Max=0,c;    int Maxi=0;    int Maxj=0;    int sum=0;    for(int i=0;i<N;i++)        scanf("%d",&a[i]);    for(int i=0;i<N;i++)    {        sum+=a[i];        if(sum>Max)        {            Max=sum;            Maxj=i;        }        if(sum<0)        {              sum=0;        }    }    c=Max;       //想了一会  实在没有什么标记的方法了  所以就用的是种方法标记的结果;    for(int i=Maxj;i>=0;i--)    {        c-=a[i];        if(c==0)        {            Maxi=i;            break;        }    }    printf("%d %d %d\n",Maxi,Maxj,Max);    return 0;}

  
原创粉丝点击