MaxSubArraySum(a, n, MaxSum, MaxStart, MaxEnd)
f ← a[0]
MaxSum ← a[0]
start ← 0
end ← 0
MaxStart ← 0
MaxEnd ← 0
FOR i = 1 TO n-1 DO
IF f > 0 THEN
f ← f + a[i] // 起点是f(i-1)的起点
ELSE
f ← a[i] // f(i)重新开始计算
start ← i // 记录新的起点位置
END
end ← i // 更新结束位置
IF f > MaxSum THEN
MaxSum ← f
MaxStart ← start
MaxEnd ← end
END IF
END FOR
起点是f(i-1)的起点
标题在这个算法中,变量f表示以当前元素结尾的连续子数组的最大和。 那么 “起点是f(i-1)的起点” 是说,
如果当前元素a[i]加入到连续子数组中后, 以a[i]结尾的连续子数组的和f[i]要起点于上一个元素a[i-1]结尾的连续子数组的起点。
就是说,如果当前元素a[i]能够使得以a[i]结尾的连续子数组的和f[i]变得更大,
那么这个连续子数组的起点应该是以a[i-1]结尾的连续子数组的起点。
为什么要求f(i-1)大于0
Kadane算法是一种高效解决最大子数组和问题的算法。该算法通过维护两个变量来实现,在遍历数组时,它会逐步计算以当前元素结尾的最大子数组和,并同时记录整个数组中最大的子数组和。
具体来说,当遍历到数组中的第i个元素时,f(i-1)表示以第(i-1)个元素结尾的最大子数组和。 如果f(i-1)小于等于0,说明以第(i-1)个元素结尾的最大子数组的和为负数或者为0,那么将其加上当前元素nums[i]得到的子数组和必然比nums[i]本身要小。因此,如果f(i-1)小于等于0,我们就没有必要将当前元素nums[i]加入到以第(i-1)个元素结尾的最大子数组中,而应该从当前元素nums[i]重新开始计算一个新的子数组。换句话说,如果f(i-1)小于等于0,那么当前元素nums[i]就会成为新的最大子数组的起始元素。
通过这种方法,Kadane算法能够在线性时间复杂度内找到最大子数组和,并且只需要遍历一次数组。同时,通过不断更新f(i-1)和start,算法可以得到最终的最大子数组的起始索引和结束索引,从而找到最大子数组。
因此,要求f(i-1)大于0的目的是为了保证当前元素nums[i]能够被纳入到以第(i-1)个元素结尾的最大子数组中,从而扩展当前的最大子数组。这样,算法就能够找到整个数组中的最大子数组和。