zoukankan      html  css  js  c++  java
  • 返回一个首尾相连的整数数组中最大子数组的和

    一、题目: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;
                }
            }
        }
    }

    五、程序运行截图:

    六、总结:

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

     

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

  • 相关阅读:
    AutoCAD.Net/C#.Net QQ群:193522571 sld文件格式的研究
    AutoCAD.Net/C#.Net QQ群:193522571 程序中需要判断是attdef和text时应该把attdef放在前面
    AutoCAD.Net/C#.Net QQ群:193522571 C#判断文件夹是否已经打开
    AutoCAD.Net/C#.Net QQ群:193522571 treeview中默认选择某一个节点
    AutoCAD.Net/C#.Net QQ群:193522571 WINFORM界面上控件的排版问题
    AutoCAD.Net/C#.Net QQ群:193522571 窗体不闪烁
    远程连接MySQL失败
    Linux后台执行任务且不打印输出到终端
    Linux升级python至3.x
    Linux运行python文件
  • 原文地址:https://www.cnblogs.com/fengyutongxing/p/4429111.html
Copyright © 2011-2022 走看看