返回一个首尾相连的整数数组中最大子数组的和

一、题目:n返回一个整数数组中最大子数组的和。

二、要求:

(1)n输入一个整形数组,数组里有正数也有负数。
(2)n数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
(3)n如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。
(4)n同时返回最大子数组的位置。
(5)求所有子数组的和的最大值。要求时间复杂度为O(n)。
三、解题思路:
    因为题目要求数组首尾相邻,允许输出A[i-1]...A[n-1],A[0]...A[j-1]之和最大,所以定义了一个n为数组,(1)从第二个整数开始到第n个整数依次向前移一位,原来第一位的整数放到最后一位,形成新的数组,(2)求新数组的最大子数组和,然后重复(1)直至循环n次,最后一个数组与初始数组相等。求最大子数组和的方法为:从第一个数(判断第一个数的正负,若负舍去,看下一个数,若正继续)开始把数组(没加一个数,都要对此数判断正负,若负,把之前的值当作最大值储存起来,再继续,若正,继续 )相加,每加一个数对和进行判断,如果小于零,抛弃当前值,如果大于零,下一个数与零比较,小于零时,先将最大值与之前的和比较,在让和加上这个数,如果大于零,直接让和加上这个数,再取最大值和和之间的最大值。(未完成时间复杂度为O(n)的要求)。
四、源代码:

 

public class test {
       
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int N=20;
        int n=-20;
        int m=20;
        int a[]=new int[N];
        
        Input(a,N,n,m);   //随机产生a[N]
        System.out.println("数组a[N]为:");
        for(int i=0;i<N;i++)     //输出数组a[N]
        {
            System.out.print(a[i]+" ");
        }
        System.out.println();
        
        int H[]={a[0],0,0};
        for(int i=1;i<=N;i++)    //求最大子数组和
        {
            array(a,N);
            Maxarray(H,3,a,N,i);
        }
        
        System.out.println("最大子数组为:");
        if(H[1]>H[2])
        {
            for(int i=H[1];i<N;i++)
            {
                System.out.print("a["+i+"]  ");
            }
            for(int i=0;i<=H[2];i++)
            {
                System.out.print("a["+i+"]  ");
            }
        }
        else if(H[1]==H[2])
        {
            System.out.print("a["+H[1]+"]  ");
        }
        else
        {
            for(int i=H[1];i<=H[2];i++)
            {
                System.out.print("a["+i+"]  ");
            }
        }
        System.out.println();
        System.out.println("最大子数组和为:"+H[0]);
        
    }
    
    static void Input(int a[],int N,int n,int m)   //随机产生数组a[N]
    {
        for(int i=0;i<N;i++)
        {
            a[i]=(int)(n+Math.random()*(m-n+1));
        }
    }
    
    static void array(int a[],int N)     //把数组第一个数放到最后,重新排列数组
    {
        int q=a[0];
        for(int i=0;i<N-1;i++)
        {
            a[i]=a[i+1];    
        }
        a[N-1]=q;
    }
    
    static void Maxarray(int H[],int L,int a[],int N,int m)   //对数组求最大子数组,并记录它的最大子数组和,和数组的起始位置
    {
        int Max=a[0];
        int A=a[0];
        int b=0;
        int c=0;
        int d=0;
        for(int i=1;i<N;i++)
        {
            if(A<0)
            {
                A=a[i];
                if(Max<A)
                {
                    Max=A;
                    b=i;
                    c=i;
                    d=b;
                }
                else
                {
                    b=i;
                }
            }
            else
            {
                if(a[i]<0)
                {
                    if(Max<A)
                    {
                        Max=A;
                        c=i-1;
                        d=b;
                    }
                    A=A+a[i];
                }
                else
                {
                    A=A+a[i];
                    if(Max<A)
                    {
                        Max=A;
                        c=i;
                        d=b;
                    }
                }
            }
        }
        if(H[0]<=Max)
        {
            H[0]=Max;
            if((d+m)<N)
            {
                H[1]=d+m;
            }
            else
            {
                H[1]=d+m-N;
            }
            if((c+m)<N)
            {
                H[2]=c+m;
            }
            else
            {
                H[2]=c+m-N;
            }
        }
    }
}

五、程序运行截图:

六、总结:

我负责编程,严雅芳负责测试。

 

此次编程最大的体会是:没有好的编程思路,拿道题不能尽快的想出解决办法,没有更好的解题思路,没有完成要求。对于自己的思路也不能很好的表达出来,不知道这可不可以在以后锻炼出来。还有感觉自己的程序比别人的复杂,代码行数太多。

posted @ 2015-04-15 17:39  风雨同行  阅读(313)  评论(1编辑  收藏  举报