一、题目概述
二、思路方向
这个问题是一个经典的算法问题,称为“最大子序和”(Maximum Subarray Problem)。解决这个问题的一个高效方法是使用“Kadane's Algorithm”,它只需要遍历数组一次,就能在 O(n) 时间复杂度内找到最大子序和。
三、代码实现
public class Solution { public int maxSubArray(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int maxSoFar = nums[0]; // 迄今为止找到的最大子数组的和 int currentMax = nums[0]; // 到目前为止包含最后一个元素的最大子数组的和 for (int i = 1; i < nums.length; i++) { // 我们想要 currentMax 保留包含 nums[i] 的最大子数组的和 // 如果加上 nums[i] 使得 currentMax 更大,则加上它 // 否则,我们从头开始,只考虑 nums[i] currentMax = Math.max(nums[i], currentMax + nums[i]); // 更新迄今为止找到的最大子数组的和 maxSoFar = Math.max(maxSoFar, currentMax); } return maxSoFar; } public static void main(String[] args) { Solution solution = new Solution(); int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; System.out.println(solution.maxSubArray(nums)); // 输出应为 6 }
}
执行结果:
四、小结
算法解释
初始化两个变量
maxSoFar
和currentMax
,两者都初始化为数组的第一个元素nums[0]
。maxSoFar
用于记录遍历过程中遇到的最大子数组和,而currentMax
用于记录包含当前元素的最大子数组和。从数组的第二个元素开始遍历,对于每个元素
nums[i]
,我们更新currentMax
。如果nums[i]
本身比currentMax + nums[i]
还要大,说明以nums[i]
结尾的最大子数组就是nums[i]
本身,我们重置currentMax
为nums[i]
。否则,我们将nums[i]
加到currentMax
上,以尝试扩展当前的最大子数组。在每次更新
currentMax
后,我们都将其与maxSoFar
进行比较,以更新迄今为止的最大子数组和。遍历完成后,
maxSoFar
就是我们要求的结果。
结语
最坚强的人
并不是能战胜一切的人
而是能承受一切的人
!!!