leetcode-53. Maximum Subarray最大子数组 python

Description

  1. Maximum Subarray Easy

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example

  • Example:

    Input: [-2,1,-3,4,-1,2,1,-5,4],
    Output: 6
    Explanation: [4,-1,2,1] has the largest sum = 6.

  • Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

题意

求一数组中元素之和最大的连续子数组(子数组至少包含一个元素),返回其最大值。

如果找到了O(n)的解法,还可以用二分法。

思路1 暴力法

暴力法就是在数组nums长度范围内以任意位置开始计算任意长度的数组,同时始终记录下元素之和最大的那个值,当所有的情况都考虑完后,就得到了最大值。其复杂度为O(n3)。
这种方法时间复杂度太高,TLE了

code

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums)==1:
            return nums[0]
        max = nums[0]
        for i in range(len(nums)):
            for j in range(i, len(nums)):
                sum = 0
                for k in range(i, j+1):
                    sum += nums[k]
                if sum > max:
                    max =sum
        return max

思路2 优化的暴力解法

思路1在计算数组的和时每次都从开始计算,这在计算过程中存在大量的重复运算,因此很容易超时。因为在以某个起始位置开始逐渐增长的长度来计算和时,只需在上次求和的基础上直接计算即可。这样就可以减少大量的重复运算。其复杂度为O(n2)。当然也TLE了。

code

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums)==1:
            return nums[0]
        maxSum = nums[0]
        for i in range(len(nums)):
            sum = 0
            for j in range(i, len(nums)):
                sum += nums[j]
                if sum > maxSum:
                    maxSum = sum
        return maxSum

思路3 动态规划

设S[i]是以下标为i的元素作为结尾的和最大的子数组,那么S[i+1]=max(S[i]+nums[i+1],nums[i+1])。为什么呢?因为S[i]已经是下标为i的元素结尾的和最大的子数组了,那么再添加nums[i+1]会不会自动是以下标为i+1结尾的和最大的子数组呢?不一定!如果S[i]<0,S[i+1]不应该将前面的加上,也即此时S[i+1]=nums[i+1],如果S[i]>0,则此时S[i+1]=S[i]+nums[i+1]。注意:我们前面已经假设了S[i]一定是以下标为i个元素结尾的和最大的子数组,这表明S[i+1]一定要以nums[i+1]结尾!

经过以上分析,我们得到了一个递推关系式,这就像数列一样。

S[0]=nums[0],S[i+1]=max(S[i]+nums[i+1],nums[i+1])。于是我们只需要利用递推关系式计算S[i]再与记录的最大值进行比较即可。这样利用递推关系只需遍历一遍数组即可计算出结果,所以时间复杂度是O(n)。

code

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        dp = [0]*len(nums)
        dp[0] = nums[0]
        for i in range(1,len(nums)):
            dp[i] = max(dp[i-1]+nums[i],nums[i])
        res = float("-inf")
        for i in range(len(dp)):
            res = max(res,dp[i])
        return res

代码优化后:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return nums[0]
        tmp = 0
        res = float('-inf')
        for i in range(len(nums)):
            tmp = max(tmp + nums[i],nums[i])
            res = max(res, tmp)
        return res

【笔记】
res = float(’-inf’)表示负无穷大,也可以用 res = -float(“inf”)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值