连续子数组的最大和(Java)

连续子数组的最大和

(牛客网—牛客题霸算法篇—NC19)

题目描述

输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
连续子数组的最大和(Java)_第1张图片

思路

Java实现

暴力穷举
穷举左右端点,使用for循环计算左右端点之间的数值之和。
优点:简单,容易理解
缺点:时间复杂度为O(n³),当n较大时,耗时。

动态规划
定义数组dp[i]表示以i结尾的连续子数组的最大和。所以最终要求dp[n-1]
状态转移方程:dp[i] = max(array[i], dp[i-1]+array[i])
时间复杂度O(n),空间复杂度O(n)

方法优化
我们可以发现当前状态只跟上一个状态有关,所以我们可以只用一个int来代替dp数组,即temp。
如果temp<0,那么这个时候就temp=array[i]
如果temp>0,那么就temp=temp+array[i]
然后再跟max比较,更新最大值。

时间复杂度O(n),空间复杂度O(1)

代码实现

暴力穷举

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int max=array[0];
        int temp;
        int i=0;
        for(i=0;i<array.length;i++){
            for(int j=i;j<array.length;j++){
                temp=0;
                for(int k=i;k<=j;k++){
                    temp=temp+array[k];
                }
                if(temp>max){
                    max=temp;
                }
            }
        }
        return max;
    }
}

动态规划

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int max=array[0];
        int len=array.length;
        int[] dp=new int[len+1];
        dp[0]=0;
        for(int i=1;i<len+1;i++){
            if(dp[i-1]>0){
                dp[i]=dp[i-1]+array[i-1];
            }else{
                dp[i]=array[i-1];
            }
            if(dp[i]>max){
                max=dp[i];
            }
        }
        return max;
    }
}

方法优化

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int max=array[0];
        int len=array.length;
        int temp=0;
        for(int i=0;i<len;i++){
            if(temp<0){
                temp=array[i];
            }else{
                temp+=array[i];
            }
            if(temp>max){
                max=temp;
            }
        }
        return max;
    }
}

你可能感兴趣的:(java,算法,数组,动态规划)