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

102 阅读2分钟

题目来源: JZ42 连续子数组的最大和

题目描述:

  • 描述: 输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。 数据范围: 1<=n<=2×105,100<=a[i]<=1001<=n<=2×10^5,−100<=a[i]<=100 要求: 空间复杂度O(n),时间复杂度O(n)
示例1:
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18  

示例2:
输入:[2]
输出:2

思路:动态规划

  • 知识点:动态规划
    • 对于这个题目,我们需要知道动态规划:其实就是将问题分解,先将分解后的小问题解决了,然后从那些分解后的小问题的解中得到最初问题的解
    • 其中,对于重复出现的小问题,只需要在第一次碰见的时候进行解决,然后将解存储起来,下次遇到的时候,直接使用第一次得到的答案,不需要进行重复解答
  • 思路:
    • 由题意可知,数组中的元素是[-100,100],因此,对于遇到的每一个数,我们就可能有三种情况,正数加入后更大了,负数加入后更小了,0加入后不变,而且我们要求的是连续的最大值,因此对于这种有状态转移的问题,我们就可以考虑使用动态规划了
  • 具体做法:
    • 1.我们可以使用dp数组用来表示以下标i作为终点的最大连续子数组和
    • 2.对数组进行遍历,每次遇到一个新的数组元素,连续的子数组要么更大,要么更小(更小,那我们就舍弃)
    • 3.因为连续数组可能会断掉,每一段只能得到该段最大值,因此我们需要维护一个最大值。
  • 图示:
    • 7BE168494FA357755FCBE09AE768AD46.gif

具体实现:

import java.util.*;
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        //记录到下标i为止的最大连续子数组和
        int[] dp = new int[array.length]; 
        dp[0] = array[0];
        int maxsum = dp[0];
        for(int i = 1; i < array.length; i++){
            //状态转移:连续子数组和最大值
            dp[i] = Math.max(dp[i - 1] + array[i], array[i]); 
            //维护最大值
            maxsum = Math.max(maxsum, dp[i]); 
        }
        return maxsum;
    }
}


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情