给定一个整数数组,找到连续子数组(至少包含一位)的最大和,并返回。
示例:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
思路
1、分治法
nums 的连续子数组的最大和,就等于以下三者中的最大值:
- nums[:mid] 的连续子数组的最大和
- nums[mid+1:] 的连续子数组的最大和
- 包含nums[mid] 的连续子数组的最大和
其中,mid 为中位数位置。
时间复杂度的递推公式:T(n) = 2*T(n/2) + n
可求出:T(n) = O(nlogn)
2、动态规划法
已知前 k 项的最大子数组之和,求前 k+1 项的最大子数组之和,就等于以下两者的较大值:
- 前 k 项的最大子数组之和
- 包含 nums[k] 的最大子数组之和
其中第2步,包含 nums[k] 的最大子数组之和,又可以根据前 k 项中包含 nums[k-1] 的最大子数组之和来得到,只需要O(1)。
因此整体时间复杂度为 O(n)。
python实现
def maxSubArray(nums):
""" :type nums: List[int] :rtype: int 分治法。 """
# 递归结束条件
l = len(nums)
if l == 1:
return nums[0]
# 求取包含nums[mid] 的连续子数组的最大和
mid = l // 2
max_sum1 = 0 # mid 左半部分的最大和(从末尾向前累加)
cur_sum = 0
for num in nums[:mid][::-1]:
cur_sum += num
max_sum1 = max(max_sum1, cur_sum)
max_sum2 = 0 # mid 右半部分的最大和(从起始向后累加)
cur_sum = 0
for num in nums[mid+1:]:
cur_sum += num
max_sum2 = max(max_sum2, cur_sum)
max_sum = nums[mid] + max_sum1 + max_sum2
# 返回三者的最大值
return max(max_sum, maxSubArray(nums[:mid]), maxSubArray(nums[mid+1:]))
def maxSubArray2(nums):
""" :type nums: List[int] :rtype: int 动态规划法 """
sub_max = nums[0] # 存储前i项的最大子数组之和
last_max = nums[0] # 存储前i项的且包含最后一位的最大子数组之和
for i in range(1, len(nums)):
last_max = max(last_max + nums[i], nums[i])
sub_max = max(sub_max, last_max)
return sub_max
if '__main__' == __name__:
nums = [-2,1,-3,4,-1,2,1,-5,4]
print(maxSubArray2(nums))