LeetCode 53. Maximum Subarray

LeetCode 53. Maximum Subarray

题目链接

分析过程

由题意,需要在给出的数组中,找出和最大的连续子数组。

解法一(不推荐)

暴力枚举。通过双重 for 循环,计算所有子数组的和,其中最大的和即为该题的结果。

代码实现略过。在 LeetCode 中,以该方式提交会导致超时。

解法二(推荐)

动态规划(DP)。将原问题转为子问题:寻找前序子数组当前数字和最大的组合。当前数字的值无法被主观控制,而前序子数组的和可以控制。因此,为达到和最大的情况,需要确保前序子数组的和大于 0,否则它就是在“帮倒忙”。
整理一下逻辑,当前序子数组的和小于 0 时,应当舍弃该前序子数组;当前序子数组的和大于等于 0 时,该前序子数组可以被加入到后续的计算中。

代码实现为:

public static int maxSubArray(int[] nums) {
    // 将最大值设置为最小的 int 值
    int max = Integer.MIN_VALUE;
    // 将临时子数组的和设置为 0
    int tmp = 0;
    // 遍历数组
    for (int num : nums) {
        // 临时子数组的值为其本身与当前遍历到的数字之和
        tmp += num;
        // 如果最大值比临时子数组的值小,则更新为临时子数组的值
        if (max < tmp) {
            max = tmp;
        }
        // (关键!)临时子数组的值小于 0,意味着在后续的计算中,当前临时子数组的加入只会让新的临时子数组的值变得更小
        // 例如:tmp = -1,则无论如何,tmp + num < num
        // 由此可得,当 tmp 的值小于 0 时,tmp 应当重置为 0
        if (tmp < 0) {
            tmp = 0;
        }
    }
    return max;
}

版权声明:本文为weixin_51112417原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。