53-Maximum-Subarray
0x0 题目详情
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
0x1 解题思路
呜,不知道怎么想的,贪心就过了(或许也可以算作动态规划吧),就是对于数组中的每一个元素i,我们都维护一个变量pre表示在i之前(包括i在内)的最大连续子数组和。
核心思路就是对于元素nums[i],我们需要判断前面产生的和pre有没有对nums[i]产生增益。所谓的产生增益就是nums[i]+pre>=nums[i],在这种情况下,我nums[i]才选择使用前面产生的和pre。否则如果nums[i]+pre<nums[i],那么在这种情况下,凭什么需要使用前面的和?nums[i]都能自立门户了,直接将pre更新为nums[i]就好。
并且不断更新最大值result。当遍历结束时就可以得到结果。
那么我们为什么不能直接使用result=Math.max(result,result+nums[i]求最大连续子数组和呢?
因为这样写,就放弃了nums[i]单独成为最大连续子数组第一个元素的机会。
那么result=max(result,result+nums[i],nums[i])对吗?
不对,对于子数组[5,-1,2]。我们在遍历到-1时,result==5,不会使用-1,但是在遇到2时,又会选择result=result+2==7,越过了中间元素-1。
所以我们必须使用两个变量。
0x2 代码实现
class Solution {
public int maxSubArray(int[] nums) {
int result=Integer.MIN_VALUE;
if(nums==null || nums.length<2){
return result=nums.length!=0?nums[0]:0;
}
//表示i之前能够产生的最大连续子数组和
int pre=0;
for(int i=0;i<nums.length;i++){
//判断i之前的子数组和加上当前元素i的结果是否比元素i本身大,如果没有,说明我们根本没有必要使用前面的子数组和
pre=Math.max(pre+nums[i],nums[i]);
//每次都更新最大值
result=Math.max(result,pre);
}
return result;
}
}0x3 课后总结
脑袋一闪,就做出来了。也许这就是灵感吧,haha.
Last updated
Was this helpful?