当先锋百科网

首页 1 2 3 4 5 6 7

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

第一种方法:暴力枚举法

class Solution:
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        sumlist = []
        for i in range(len(nums)-1):
            sum = nums[i]
            sumlist.append(nums[i])
            for j in range(i+1,len(nums)):
                sum+=nums[j]
                sumlist.append(sum)
        sumlist.append(nums[len(nums)-1])
        return max(sumlist)

思想很简单,就是枚举所有的可能的情况,自然而然复杂度就很高啦,一看就是o(n^{2}),不建议这样,这只是一种笨方法,而且运行时还超时了,这是最关键的。那自然而然我们要想其他方法。

第二种方法:动态规划(极力推荐)

思路:

最大和连续子数组一定有如下几个特点:

1、第一个不为负数

2、如果前面数的累加值加上当前数后的值会比当前数小,说明累计值对整体和是有害的;如果前面数的累加值加上当前数后的值比当前数大或者等于,则说明累计值对整体和是有益的。

步骤:

1、定义两个变量,一个用来存储之前的累加值,一个用来存储当前的最大和。遍历数组中的每个元素,假设遍历到第i个数时:

①如果前面的累加值为负数或者等于0,那对累加值清0重新累加,把当前的第i个数的值赋给累加值。

②如果前面的累加值为整数,那么继续累加,即之前的累加值加上当前第i个数的值作为新的累加值。

2、判断累加值是否大于最大值:如果大于最大值,则最大和更新;否则,继续保留之前的最大和

class Solution:
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        maxsum = nums[0]
        presum = 0
        for i in range(len(nums)):
            if presum<0:
                presum = nums[i]
            else:
                presum+=nums[i]
            if presum>maxsum:
                maxsum = presum
        return maxsum

时间复杂度:很容易看出,这个算法的时间复杂度为o(n)

最后提一下,还有一个算法的时间复杂度为o(nlogn),这个算法是分治法。这里就不做阐述了。