Dynamic Programming学习笔记 (31) - 最大和的连续子数组 (力扣# 53)

90 阅读1分钟

本题出自力扣题库第53题。题面大意如下:

给定一个整数数组 nums ,找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

实例:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

题解:

以长度为4的数组为例,所有可能的连续子数组的排列为

  [0]

  [0][1]
      [1]

  [0][1][2]
      [1][2]
          [2]

  [0][1][2][3]
      [1][2][3]
          [2][3]
              [3]

  [0][1][2][3][4]
      [1][2][3][4]
          [2][3][4]
              [3][4]
                  [4] 

我们可以看到,对于某个数组下标而言,其对应的所有连续子数组都在下一个下标的连续子数组中出现,也就是说,我们可以用如下的DP表达式来描述这个问题。

F(k) 
  = nums[0], k = 0
  = max (F(k - 1) + nums[k],  nums[k])

这里k是数组下标,F(k) 返回的是包含前k个数组元素的所有连续子数组之和的最大值,也就是F(k - 1) + nums[k]和nums[k]之间较大的一个。

从以上表达式出发,我们使用一个单层循环来依次计算每个数组下标所对应的最大连续子数组之和,并记录全局的最大值作为最终的返回结果。

Java代码如下:

class Solution {
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        if (n == 1) {
            return nums[0];
        }

        int result = nums[0];
        int max = nums[0];
        for (int i = 1; i < n; i ++) {
            max = Math.max(max + nums[i], nums[i]);
            result = Math.max(max, result);
        }
        return result;
    }
}