Leetcode 第53题(最大子数组和)

最大子数组和

Leetcode 第53题(最大子数组和)_第1张图片
这道题使用动态规划法,动态规划最最核心的思想就是根据 前n-1个状态(步),求第n个状态(步),拿本题来说,以每个元素为子数组结尾的话可以分成n个状态,比如nums = [-2,1,-3,4,-1,2,1,-5,4],就有子数组以‘-2’结尾、‘1’结尾、‘-3’结尾、‘4’结尾、‘-1’结尾、‘2’结尾、‘1’结尾、‘-5’结尾、‘4’结尾 9个状态,我们把它们按顺序0-8排列,’-2’,‘1’…分别是状态0、1…的值,这里的思想就是根据状态 0 求状态 1,根据状态1求状态2,…,根据状态7求状态8(注意:求状态2只需要状态1,是因为状态1是根据状态0求得的,所以在求状态2的时候不需要状态0了,后面类似)。

具体一点,本题是要求最大子数组和,那我们就把每个状态下的最大子数组和求出来,再返回最大值。比如:
状态0:以‘-2’结尾的子数组有[-2]一个,我们要求最大子数组和,所以就是-2;
状态1:以‘1’结尾的子数组有[-2,1]、**[1]**两个,最大为1;
状态2:以‘-3’结尾的子数组有[-2,1,-3]、 [1,-3] 、[-3]三个,最大是-2;

上面说根据状态n-1求状态n,所以我们要找出相邻两个状态之间的关系,我们也叫状态转移函数,这也是题目最大的难点,或许能想到使用动态规划法,但是不一定能构建出状态转移函数。

这里的关系是 f(n) = max (f(n-1)+n, n)

f(n)代表状态n下的最大子数组和,n代表状态n的值。

比如要求状态1下的最大子数组和,我们要比对(状态0的最大和 加上 现在状态1下的值‘1’ )和 (现在状态的值) 谁更大,也就是说,上一个状态0与我们现在的状态1连接后能否让状态1变得更好,实际上,也就是如果上一个状态下求得的最大和是负值,我们就不连接上一个状态了。具体来看:

[-2,1,-3,4,-1,2,1,-5,4]

状态1:-2 + 1 < 1,1
状态2:1 + (-3) > -3,-2
状态3:-2 + 4 < 4,4
状态4:4 + (-1) > -1,3
状态5:3 + 2 > 2,5

这里因为只有把每个状态下的最大子数组和求出来,所以在写程序时还要选出最大的那个子数组和,下面是代码:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        p = 0
        sum = 0
        ans = nums[0]
        while p<n:
            sum = max(sum+nums[p],nums[p])  #状态转移函数
            if ans<sum:    #选出最大的最大子数组和
                ans = sum
            p += 1
        return ans

时间复杂度:O(n)
空间复杂度:O(1)

还有一种分治法,后面补上…

你可能感兴趣的:(Leetcode,python)