zoukankan      html  css  js  c++  java
  • 子数组的和的最大值(包括升级版的首尾相连数组)

    一、题目要求:

    输入一个一维整形数组,数组里有正数也有负数。

    一维数组首尾相接,像个一条首尾相接带子一样。

    数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。

    发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选)、源代码、结果截图、总结。

    二、程序设计思想

    对于一个数组来讲,要想求最大的子数组,是一件很简单的事,但是一旦要求时间复杂度为O(n)后,情况就不一样了。

    那么怎么做呢,首先对于一个数组有三种大的情况,一种是全是正的,一种是全是负的,另外一种是有正有负的,如果全是正的或全是负的,那么很简单,全是正的时候,全部相加就是子数组和的最大值,全是负的时候,数组中最大的那个数字就是子数组的和的最大值。那么有正有负的该怎么做呢?

    我就想到,申明一个最大值数组,temp变量作为中间值,如果发现当前的最大值与下一个数相加之后大于零,那么就令最大值等于最大值与下个数相加的和,如果小于最大值,并且大于0,那么就用temp加上下一个数,如果小于零,那么就令temp=0,max数组向后移一位,然后令该max重新等于零,一直重复此操作,最后在从max数组里找出最大的那个就是子数组的和的最大值。

    三、源代码:

    public class MaxIntArray {
        public static void main(String [] args){
            int a[]={1,4,5,6,2};
            int Max[]=new int[5];
            Max[0] = 0;
            int i = 0;//数组下标
            int j = 0;//最大值数组下标
            int temp=0;//中间变量
            while(i<a.length){                
                    if(temp+a[i]>=Max[j])
                    {
                        temp=temp+a[i];
                        Max[j]=temp;
                        i++;
                    }
                    else if(temp+a[i]<Max[j]&&temp+a[i]>0)
                    {
                        temp=temp+a[i];
                        i++;
                    }
                    else if(temp+a[i]<=0)
                    {
                       i++;    
                       j++;
                       Max[j]=0;
                       temp=0;
                    }
                
            }
            int max = Max[0];
            for(int k=0;k<=j;k++){
                if(Max[k]>max)
                {
                    max=Max[k];
                }
            }
            /*System.out.println(j);
            for(int k=0;k<=j;k++){
                System.out.println(Max[k]);
            }*/
            System.out.println("最大子数组和为"+max);
        }
    }

    首尾相连的代码:

    public class Max2 {
        public static void main(String [] args){
            int a[]={2,4,3,-9,9,9,-1};
            int b[]=new int[100];
            int n=a.length;
            for(int i=0;i<n;i++){
                b[i]=a[i];
                b[i+n]=a[i];
            }
            
            int Max[]=new int[10];
            Max[0] = 0;
            int i = 0;//数组下标
            int j = 0;//最大值数组下标
            int temp=0;//中间变量
            int q=1;//用于连续长度的计数
            while(q<a.length&&i<b.length){                
                    if(temp+b[i]>=Max[j])
                    {
                        temp=temp+b[i];
                        Max[j]=temp;
                        i++;
                        q++;
                    }
                    else if(temp+b[i]<Max[j]&&temp+b[i]>0)
                    {
                        temp=temp+b[i];
                        i++;
                        q++;
                    }
                    else if(temp+b[i]<=0)
                    {
                       i++;    
                       j++;
                       Max[j]=0;
                       temp=0;
                       q=1;
                    }
                
            }
            int max = Max[0];
            for(int k=0;k<=j;k++){
                if(Max[k]>max)
                {
                    max=Max[k];
                }
            }
            /*System.out.println(j);
            for(int k=0;k<=j;k++){
                System.out.println(Max[k]);
            }*/
            System.out.println("最大子数组和为"+max);
        }
    
    }

    四、程序结果截图:

    4组不同的测试用例:

    首尾相连的测试用例:

    五、总结:

    一个人的力量终究有限,这次作业我是和许磊共同完成的,在写程序之前,我们经过了激烈的讨论,以及相当长的时间的思考,最终解决了问题。

    同时,我们也切实的体会到了合作所带来的好处。

     

  • 相关阅读:
    解释器模式
    命令模式
    责任链模式
    代理模式
    享元模式
    外观模式
    装饰器模式
    组合模式
    过滤器模式
    js广告浮动
  • 原文地址:https://www.cnblogs.com/haojun/p/6652837.html
Copyright © 2011-2022 走看看