结队完成-连续最大子数组和

要求:

时间复杂度 O(n)

连续子数组要求和最大

从数组任意一个地方均可开始

参考来源:

http://www.cnblogs.com/waytofall/archive/2012/04/10/2439820.html

苦恼啊:

从网上和慧慧的程序中都发现了不完善之处,计算是轮了两圈之后的结果:

//慧慧基础上将数组改成 6 -3 -2 8 -4 验证。正确答案  为10
package test2;
//从每一个正数位置开始,往后加若和为负数,则将上一个和放在链表,并进行下一个位置
import java.util.Scanner;
public class Maxchoose
{
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            /*
              System.out.print("请输入数组的长度N=");
             
            Scanner scan=new Scanner(System.in);
            int length=scan.nextInt();
            int arr[]=new int[length];
            int arr2[]=new int[2*length-1];//首尾相连接时
            for(int i=0;i<length;i++)
            {
                arr[i]=(int)(10-Math.random()*20);  //产生-10到10的随机数
            }
            */
            
            int length=5;
            int arr[]={6,-3,-2,8,-4};
            int arr2[]={6,-3,-2,8,-4,6,-3,-2,8};
            
            System.out.print("数组:{ ");
            for(int i=0;i<length;i++)
            {
                System.out.print(arr[i]+" ");
                }//用于验证数组
            System.out.println("}");
            System.out.print("首尾相接数组:{ ");
            for(int m=0;m<2*length-1;m++)
            {
                if(m<length)
                {
                    arr2[m]=arr[m];
                    }
                else
                {
                    arr2[m]=arr[m-length];
                    }
                System.out.print(arr2[m]+" ");//用于验证首尾相接数组
                }
            System.out.println("}");
            int max=0;
            int curSum=0;
            int curIndex=0;
            int start=0;
            int end=0;
            for(int j=0;j<2*length-1;j++)
            {
                if(j==0)
                {
                    max=arr2[j];
                    curSum=max;
                    continue;
                    }
                if(curSum<0)
                {
                    curSum=0;
                    curIndex=j;
                    }
                curSum+=arr2[j];
                if(curSum>max)
                {
                    max=curSum;
                    start=curIndex;
                    end=j;
                    }
                }
            System.out.print("子数组和最大为:{");
            for(int i=start;i<=end;i++){
                System.out.print(arr2[i]+" ");
            }
            System.out.print("}
   值为"+max);
        }
    }//end
View Code

输出错误结果:

本应该是 {8 , -4 , 6}

发现此程序中的特点;

每一个最大字数组的开始和结束都是正数,如果开始元素加上后面的元素为正数就能继续加下去。

但是,我放弃,我投降,我缴械。

package test1;

import java.util.Scanner;

public class Test {
    static List vet=new List();
    public static void main(String[] args) {
            
            int a1[]={8,-4,6,-3,-2};
            int a2[]={6,-3,-2,8,-4,6,-3,-2,8};  
            //int a[]={-1,-2,-3,-4};  //测试全是负数的用例  
            int b[]=new int[a1.length];
            for(int i=0;i<a1.length;i++)
            {
                   b[i]=maxSum(a2,i,a1.length);
               }
            
            
            System.out.println("最大和为"+mm(b));
        }  
          
    public static int mm(int b[])
    {
        int max=0;
        for(int i=0;i<b.length-2;i++)
        {
            if(b[i+1]>b[i])
                max=b[i+1];
        }
    return max;
    }
    
    public static int maxSum(int a[],int n,int m)  
        {  
            int sum=0;  
            
            //其实要处理全是负数的情况,很简单,如稍后下面第3点所见,直接把这句改成:"int sum=a[0]"即可  
            //也可以不改,当全是负数的情况,直接返回0,也不见得不行。  
            int b=0;  
            for(int i=n; i<n+m; i++)  
            {  
                if(b<0)           //...  
                    b=a[i];  
                else  
                    b+=a[i];  
                if(sum<b)  
                    sum=b;  
            }  
            return sum;  
        }  
}
View Code

结果:

本数组int a1[]={8,-4,6,-3,-2};
      int a2[]={6,-3,-2,8,-4,6,-3,-2,8}; 

最大数组和  10

(6, -4 ,8)

原文地址:https://www.cnblogs.com/Amyheartxy/p/6635165.html