一个整形数组中最大值求和问题--数组

要求:

1.输入一个整形数组,数组里面有正数也有负数。

2.数组中国连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

3.求所有子数组的和的最大值。要求时间复杂度为O(n)。

当自己看到这个题目的时候,想到了“复杂的问题简单化,一步一步来”,然后在课上老师的引导之下有了自己实现这个功能的方法。最终自己用了两者方法实现功能,但是在第二种方法上花费的时间较多,几乎是第一种方法两倍的时间。下面将两种方法一一解释自己的思路。

一、时间复杂度O(n^2)

本次功能实现简单,一共分为3步,首先是实现数组的输入,然后进行一个或多个连续子数组的求和,最后进行比较。但需要注意的是,求和以及比较是同时存在的。

本次实现功能的过程中遇到了一个小小的问题,就是将自己用来记录最大值的变量f赋初值为0,忽略了数组中的值全为负数时的情况,最终解决将f赋初值为数组中第一个数,解决了问题。

以下是完整代码以及测试结果:

import java.util.Scanner;

public class sum01 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        //整形数组的输入
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数组的长度为:");
        int n=sc.nextInt();
        int[] c = new int[n];
        System.out.println("请输入"+n+"个整数");
        for(int i=0;i<n;i++)
        {
            c[i] = sc.nextInt();
        }
        
        //子数组求和以及大小比较
        int f=c[0];//定义整形变量f,为子数组最大值
        int sum=0;//定义整形变量sum,为子数组求和
        for (int j=0;j<n;j++) 
        {
        for (int i=j;i<n;i++)
        {
            sum=sum+c[i];
            if(f<sum)
            {
                f=sum;//每次求和之后将sum与已有的最大值进行比较
            }
        }
            sum=0;
        }
        
        System.out.println("该数组的子数组之和的最大值为:"+f);
}

二、时间复杂度O(n)

第二种方案就是实现要求中时间复杂度为O(n)的问题,该程序的设计思想是,从数组中第一个值开始进行加法运算,如果sum值加到某数为负(包括数组中所有整数为负的情况),则将sum值归0(因为数组的子数组为连续,所以sum值可以直接归0),如果sum值大于已有的最大值f,那么给f赋新值sum,如此循环直至数组遍历一遍,最终如果sum不为零,则计算结果就是最大整数,若sum值为0,才需二次遍历数组寻找数组中的最大值。

以下是完整代码以及测试结果:

import java.util.Scanner;

public class sum02 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数组的长度为:");
        int n=sc.nextInt();
        int[] c = new int[n];
        System.out.println("请输入"+n+"个整数");
        for(int i=0;i<n;i++)
        {
            c[i] = sc.nextInt();
        }
        
        int f=0;//定义整形变量f,为子数组最大值
        int sum=0;//定义整形变量sum,为子数组求和
        for(int i=0;i<n;i++)
        {
            sum = sum+c[i];
            if(sum < 0)
            {
                sum=0;
            }
            if(sum > f)
            {
                f = sum;
            }
        }
        
        if(sum == 0)
        {
            for(int i=0;i<n;i++)
            {
                if(i == 0)
                {
                    f = c[i];
                }
                if(f < c[i])
                {
                    f = c[i];
                }
            }
        }
        
        System.out.println("该数组的子数组之和的最大值为:"+f);

    }

}

此外,在课上还有许多同学提出了自己的观点,首先将数组的最大值找出,然后在围绕最大值进行求和运算的方法也是可行的,但自己还没有用代码进行实现,但同学的设计思路自己已经明白了。

一问多解,像极了自己以前热爱的数学问题,生活中许多问题也是这样,真神奇!

原文地址:https://www.cnblogs.com/Qi77/p/10505647.html