题目描述
// 42. 连续子数组的最大和
// 力扣
// 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。
// 求所有子数组的和的最大值。
// 要求时间复杂度为O(n)。
// 牛客
// 输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整
// 数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
题解
// 暴力法
// 暴力法在力扣无法通过
// 牛客
// 运行时间:10ms
// 占用内存:9448k
public class Solution {
private int max = 0;
public int FindGreatestSumOfSubArray(int[] array) {
if (array.length == 0)
return 0;
max = array[0];
for (int i = 0; i < array.length; i++) {
int pathSum = 0;
for (int j = i; j < array.length; j++) {
pathSum += array[j];
if (pathSum >= max)
max = pathSum;
}
}
return max;
}
}
// 动态规划 //
// 牛客
// 运行时间:10ms
// 占用内存:9544k
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
if (array.length == 0)
return 0;
int max = array[0]; // 将max初始化为array第一个元素
int pathSum = 0; // 当前遍历子数组路径的和记为pathSum
for (int val: array) { // 遍历array中的元素记为val
if (pathSum <= 0) // 如果pathSum不是正值,加val也不会使val增多
pathSum = val; // 还不如直接令pathSum修改为当前的val
else // 如果pathSum是正值,不管val是正是负,都会对val有增加
pathSum += val; // 所以此时pathSum直接累加val
if (pathSum >= max) // 每次运算将大数保存至max
max = pathSum;
}
return max;
}
}
// 看完上面的注释,还需要补充一点的是:
// 这道题需要连续的子数组,我们遍历数组一定是从左往右,
// val是一定要加的,不可能跳过val去加下一个,而pathSum是之
// 前遍历的子数组的和,是可以保留也可以放弃的。
// 因此pathSum的处理上,我们通过判断pathSum对val值的增益与否,
// 来选择是否累加val,还是直接将pathSum重置为val。
// (而不是判断val的正负与否来累加,因为val是一定要加的。)
// 力扣
// 执行用时:1 ms, 在所有 Java 提交中击败了97.97%的用户
// 内存消耗:45 MB, 在所有 Java 提交中击败了42.77%的用户
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 0)
return 0;
int max = nums[0];
int pathSum = 0;
for (int val: nums) {
if (pathSum <= 0)
pathSum = val;
else
pathSum += val;
if (pathSum >= max)
max = pathSum;
}
return max;
}
}