由简入难,先从最简单的问题的入手吧:
给出一个整形数组,问最大子数组的和是多少?要求数组连续。
输入样例:nums = [-3,4,-1,2,1,-5,4]
输出样例:6,即连续子数组[4,-1,2,1]的和最大
思路很简单:
可以DP,但没必要。可以这样理解:当之前已有的数组和大于0时,则它必然对于此时的和有贡献,因此在其基础上累加(if sum > 0 : sum += nums[i]
);当之前已有的数组和小于0时,则此时应该另起炉灶(if sum < 0 : sum = nums[i]
)。
代码也简单:
class Solution {
public int maxSubArray(int[] nums) {
int max = nums[0];
int sum = nums[0];
for (int i = 1; i < nums.length; i++) {
sum = nums[i] + (sum > 0 ? sum : 0);
max = Math.max(max, sum);
}
return max;
}
}
更进一步,如果想要的是最大数组位置而非最大数组和:
思路也不难:
仍旧需要维护最大值max、数组和sum;设置一个start表示数组左边界,而右边界就是当前的位置i,不用专门设置变量;
想一个重要的问题,start在何时更新呢?在由于sum小于0而另起炉灶时更新start。
代码如下:
class Solution {
public int[] maxSubArray(int[]