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;
}