题目:
原题链接: https://leetcode-cn.com/problems/maximum-subarray/
解题思路:
1. 经典最大子序列求和算法,时间复杂度O(N),流程如下:
变量如下:
- max_sum,最大和,初始化为float('-inf')
- curr_sum,当前和,初始化为0
- curr_num,当前遍历到的元素
算法流程如下:
- 从前向后遍历数组,每遍历一个数字,更新curr_sum = curr_sum + curr_num
- 如果curr_sum > max_sum,则更新max_sum = curr_sum
- 如果curr_sum < 0,则更新curr_sum = 0
2. 分治法,时间复杂度为O(NlogN),练习分治法的好题目
分治法的一般思路如下:
- 定义基本情况
- 将问题分解为子问题并递归地解决它们
- 合并子问题的解以获得原始问题的解
对于此题,分治法的步骤如下:
变量如下:
- n:当前处理的子串中元素个数
- left : 当前子串的起点索引
- right : 当前子串的终点索引
- left_sum : left到(left + right) / 2元素的连续最大子序列的和
- right_sum : (left + right) / 2到right元素的连续最大子序列的和
- cross_sum: 包含左右子数组且含索引
(left + right) / 2
的最大值算法图解如下:
代码实现:
方法一:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
curr_sum, max_sum = 0, float('-inf')
for curr_num in nums:
curr_sum += curr_num
if curr_sum >= max_sum:
max_sum = curr_sum
if curr_sum < 0:
curr_sum = 0
return max_sum
方法二:
class Solution:
def cross_sum(self, nums, left, right, p):
if left == right:
return nums[left]
left_subsum = float('-inf')
curr_sum = 0
for i in range(p, left - 1, -1):
curr_sum += nums[i]
left_subsum = max(left_subsum, curr_sum)
right_subsum = float('-inf')
curr_sum = 0
for i in range(p + 1, right + 1):
curr_sum += nums[i]
right_subsum = max(right_subsum, curr_sum)
return left_subsum + right_subsum
def helper(self, nums, left, right):
if left == right:
return nums[left]
p = (left + right) // 2
left_sum = self.helper(nums, left, p)
right_sum = self.helper(nums, p + 1, right)
cross_sum = self.cross_sum(nums, left, right, p)
return max(left_sum, right_sum, cross_sum)
def maxSubArray(self, nums: 'List[int]') -> 'int':
return self.helper(nums, 0, len(nums) - 1)
作者:LeetCode
链接:https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。