前言:剑指offer刷题系列
问题:
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例:
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路:
看到这个题目思考了一下,就有了如下思路:
- first,定义一个变量 maxnum,用来记录全局的最大子数组和,初始化为数组的第一个元素 nums[0]。
- second,遍历数组中的每个元素 nums[i],从第二个元素开始,用一个变量 last_num 记录前一个元素 nums[i-1] 的值。
- then,判断 last_num 是否大于 0,如果是,说明它对当前元素 nums[i] 有增益效果,可以将它们相加得到更大的子数组和,并更新 nums[i] 的值;如果不是,说明它对当前元素 nums[i] 没有增益效果,可以直接舍弃它,保持 nums[i] 的值不变。
- last,比较 maxnum 和 nums[i] 的大小,取较大者作为新的 maxnum,并继续遍历下一个元素。
遍历完整个数组后,maxnum 就是最大子数组和,返回它即可。
基于上述思考,代码如下:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
maxnum = nums[0]
for i in range(1,len(nums)):
last_num = nums[i-1]
if last_num > 0:
nums[i] += last_num
maxnum = max(maxnum,last_num)
return maxnum
执行结果如下图:
学到的知识点:
动态规划类型的题目,对我来说还是优点难的,但是这类题目一般是将一个较难的题目,分解为较简单的子问题。 一般首先按照问题的时间或空间特征,把问题分为若干个阶段。在每个阶段都需要作出决策,从而影响下一个阶段的状态。然后就是确定状态:用一个或多个变量来描述每个阶段的状态,即问题在该阶段所处的情况。状态一般是历史决策的结果,也是未来决策的依据。然后,根据不同的状态,考虑在当前阶段可以做出什么决策,以及做出这个决策后会产生什么后果,从而确定下一个阶段的状态。通过递推或者逆推的方式,找出每个状态下的最优策略,即能够使得整个问题达到最优解的决策。最后构造最优解:根据每个状态下的最优策略,从初始状态开始,逐步执行决策,直到结束状态,得到最优解。