LeetCode:53. 最大子序和(python)
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
思路:
-
动态规划
-
记录当前位置前的子序列和状态
-
若大于 0,表示有助于后序数字和的增加,则更新状态
-
若小于(等于) 0,表示有损于(无益于)后序数字和的增加,则舍弃
-
-
记录子序列和最大值
-
-
分治法
- 最大子序和位于左子序、中间子序、右子序
附代码(Python3):
-
动态规划
class Solution: def maxSubArray(self, nums): if not nums: return None res = cur = nums[0] # 初始化最大子序和、状态值 for i in range(1, len(nums)): # 若 cur 大于 0,有助于后序数字和的增加,则更新 cur(叠加当前数字); # 若 cur 小于(等于) 0,有损于(无益于)后序数字和的增加,则更新 cur 为当前数字 if cur > 0: cur += nums[i] else: cur = nums[i] res = max(res, cur) # 更新最大子序和 return res
test = Solution() nums = [-2,1,-3,4,-1,2,1,-5,4] test.maxSubArray(nums)
6
-
分治法
# 分治法 class Solution: def maxSubArray(self, nums): n, mid = len(nums), len(nums)//2 if n == 1: return nums[0] # 递归截止 else: max_left = self.maxSubArray(nums[:mid]) # 左序列最大子序和 max_right = self.maxSubArray(nums[mid:]) # 右序列最大子序和 # 中间序列最大子序和(max_l + max_r) max_l = cur = nums[mid-1] # 初始化左中位数为左侧子序和最大值和状态值 for i in range(mid-2, -1, -1): cur += nums[i] max_l = max(max_l, cur) max_r = cur = nums[mid] # 初始化右中位数为右侧子序和最大值和状态值 for i in range(mid+1, n): cur += nums[i] max_r = max(max_r, cur) return max(max_left, max_right, max_l+max_r)
test = Solution() nums = [-2,1,-3,4,-1,2,1,-5,4] test.maxSubArray(nums)
6