剑指Offer 42 : 连续子数组的最大和,即最大子序和问题。
算法描述
- 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
- 示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
代码描述
主要的算法描述可以参见《剑指Offer》P218-P220,基本思想如下图所示:
class Solution(): # the optimum algorithm
def func(self, mylist):
if mylist == None or len(mylist) == 0:
return 0
maxValue = 0
curValue = mylist[0]
for i in range(len(mylist)):
if curValue < 0:
curValue = mylist[i]
else:
curValue += mylist[i]
if curValue > maxValue:
maxValue = curValue
return maxValue
在力扣网上还有人给出了分治法的题解,说实话我觉得可能还不如动态规划的思想,但是为了完整还是贴出别人写的分治法的思想吧:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
#递归终止条件
if n == 1:
return nums[0]
else:
#递归计算左半边最大子序和
max_left = self.maxSubArray(nums[0:len(nums) // 2])
#递归计算右半边最大子序和
max_right = self.maxSubArray(nums[len(nums) // 2:len(nums)])
#计算中间的最大子序和,从右到左计算左边的最大子序和,从左到右计算右边的最大子序和,再相加
max_l = nums[len(nums) // 2 - 1]
tmp = 0
for i in range(len(nums) // 2 - 1, -1, -1):
tmp += nums[i]
max_l = max(tmp, max_l)
max_r = nums[len(nums) // 2]
tmp = 0
for i in range(len(nums) // 2, len(nums)):
tmp += nums[i]
max_r = max(tmp, max_r)
#返回三个中的最大值
return max(max_right,max_left,max_l+max_r)