【LeetCode 简单题】11-最大子序和

声明:

今天是第11道题。给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。以下所有代码经过楼主验证都能在LeetCode上执行成功,代码也是借鉴别人的,在文末会附上参考的博客链接,如果侵犯了博主的相关权益,请联系我删除

(手动比心ღ( ´・ᴗ・` ))

啊啊啊啊这篇博文整整写了1个上午啊,保持专注的话1个半小时应该就够,慢慢来吧~~~~~~

正文

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

示例:

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

进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

解法1。遍历整个数组,数之和用sum记录,最大和用max记录,初始值分别为0,nums[0]。如果sum累加当前元素>=0,则选择累加(此元素小于0的话,max就不更新,所以max能保证无论sum怎么加,max都记录的是sum历史最大值),如果sum累加当前元素<0,则令sum置0,同时比较当前元素和max大小来选择是否更新max

class Solution:
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # V 1.0,能提交
        sum = 0
        max = nums[0]
        for num in nums:
            if sum + num >= 0:
                sum += num
                if sum > max:
                    max = sum
            else:
                sum = 0
                if num > max:    # 这一步并不是多余的,试想如果nums全负的话,这里可以用max获取到数组的最大值
                    max = num
        return max

 解法2。比解法1更耗费时间,穷举了所有可能性并存储起来,能运行正确,但提交超时,基本思路就是2个循环嵌套,每轮把所有加和情况放到数组sums中,计算出1个最大值,下一轮出现更大的就更新。

class Solution:
    def maxSubArray(self, nums):
        i = 0
        result = nums[0]
        len_nums = len(nums)
        # 用2个循环嵌套,穷举所有加和可能性放在sums里,每一个外层循环中比较出当次的最大值存到result,下一轮如果存在更大的和就更新result,但是非常耗时
        while i < len_nums:
            temp = 0
            sums = []
            for j in range(i,len_nums):
                temp += nums[j]
                sums.append(temp)
            if result < max(sums):
                result = max(sums)
            i += 1
        return result

解法3。 分而治之思想。把输入数组分为左、右两边,最长子序列有3种情况,1-在左边,2-在右边,3-左右通过中间元素相连,1和2的实现通过递归调用divide函数求取所有可能情况的最大值,3通过从中间元素的两边开始计算和,把最大值记录在*_border_max中。具体实现如下

class Solution:
    def divide(self,nums,left,right):
        if left < right:
            return -2147483647
        mid = int((left+right)/2)

        # 情况3-从中间往左一位开始求左边的最大值,考虑和中间元素相连
        sum = 0
        left_border_max = 0
        for i in range(mid-1,left-1,-1):
            sum += nums[i]
            left_border_max = max(left_border_max, sum)

        # 情况3-从中间往右一位开始求右边的最大值,考虑和中间元素相连
        sum = 0
        right_border_max = 0
        for i in range(mid+1,right+1):
            sum += nums[i]
            right_border_max = max(right_border_max, sum)
        
        # 情况1、2-求左、右两边的最大值,不考虑和中间元素相连
        left_max = self.divide(nums,left,mid-1)
        right_max = self.divide(nums,mid+1,right)

        # 返回3种情况的最大值
        return max(left_border_max+nums[mid]+right_border_max,max(left_max,right_max))

    def maxSubArray(self, nums):
        # 调用求最长子序列的函数
        return self.divide(nums,0,len(nums)-1)

结尾

解法1:https://blog.csdn.net/u012860582/article/details/80483102

解法2:https://blog.csdn.net/qq_34364995/article/details/80284270

解法3:https://blog.csdn.net/qqxx6661/article/details/78167981

猜你喜欢

转载自blog.csdn.net/weixin_41011942/article/details/82620198
今日推荐