求连续子数组和的最大值

题目描述:

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,那么该数组中连续的最大的子数组为3, 10, -4, 7, 2,则输出为该子数组和最大值18。

输入的数组为 -2,-8,-7,-1,-10,那么该数组中最大的子数组为 -1,则输出的该子数组和的最大值为 -1。

思路参考

用total记录累计值,maxSum记录和最大。

基于思想: 对于一个数A,若是A的左边累计数非负,那么加上A能使得值不小于A,认为累计值对整体和是有贡献的。

      如果前几项累计值负数,则认为有害于总和,total记录当前值。

此时 若和大于maxSum 则用maxSum记录下来

public class Solution 
{
    public int FindGreatestSumOfSubArray(int[] array)
    {
        if(array.length == 1)//只有一个元素
            return array[0];
        else
        {
            int total = array[0];//不能设置为0,防止元素均为负数
            int maxSum = array[0];
            for(int i=1; i<array.length; i++)
            {
                if(total >= 0)
                    total += array[i];
                else
                    total = array[i];//否则,total记录当前值
                if(total > maxSum)
                    maxSum = total;
            }
            return maxSum;
        }
        
    }
}

 参考思路2:动态规划

用F(i)表示以array[i]为末尾元素的连续子数组和的最大值,则F(i) =max( F(i-1) + array[i], array[i] )

result:所有子数组的和的最大值,result=max(result,F(i))

如数组[6, -3, -2, 7, -15, 1, 2, 2]

初始状态:

    F(0)=6

    res=6

i=1:

    F(1)=max(F(0)-3,-3)=max(6-3,3)=3

    res=max(F(1),res)=max(3,6)=6

i=2:

    F(2)=max(F(1)-2,-2)=max(3-2,-2)=1

    res=max(F(2),res)=max(1,6)=6

i=3:

    F(3)=max(F(2)+7,7)=max(1+7,7)=8

    res=max(F(2),res)=max(8,6)=8

i=4:

    F(4)=max(F(3)-15,-15)=max(8-15,-15)=-7

    res=max(F(4),res)=max(-7,8)=8

以此类推

最终res的值为8

public class Solution 
{
    public int FindGreatestSumOfSubArray(int[] array) 
    {
        int result = Integer.MIN_VALUE;
        int maxValue = array[0];
        for(int i=1; i<array.length; i++)
        {
            maxValue = Math.max(maxValue + array[i], array[i]);
            result = Math.max(result, maxValue);
        }
        return result;
    }
}

若想自己编写测试用例:

        int ArrayLength = 8;//数组大小
        int [] arr = new int [ArrayLength];
        //Scanner 输入数组并读取的方法输入
        Scanner sc = new Scanner(System.in);
        for(int i = 0; i < arr.length; i++)
        {
            arr[i] = sc.nextInt();
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值