LeetCode 算法题库【53】——最大子序和

最大子序和

题目描述:

zuidazixuhe

做题思路:
  • 第一种:这种方法比较容易想到,但是写起来需要仔细推一推。我们先是从0开始,定义tempmaxinums[0],然后开始从1开始循环,即从列表nums的第二个数开始,先让它和第一个数相加,看其是否大于自己本身,如果大,则最大子序和很有可能会出现在后面序列中,然后将此时的最大值重新赋值给maxi,然后将前面temp + nums[i]又赋值给temp,以此类推。反之,如果小,则我们重新以这个元素为起点开始往下找最大子序和,同时也记录最大值赋给maxi
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        lens = len(nums)
        temp = maxi = nums[0]
        for i in range(1, lens):
            if temp +  nums[i] > nums[i]:
                maxi = max(maxi, temp + nums[i])
                temp = temp + nums[i]
            else:
                temp = nums[i]
                maxi = max(maxi, temp)
        return maxi

1

  • 第二种:这个方法是学习了别人的方法,官方叫贪心算法。确实特别厉害,从开始一直在遍历数组然后重复取最大值,如果temp + nums[i]最大,则继续往下加求得最大子序,如果nums[i]最大,则从这个数重新开始往下找最大子序。通过不断地更新当前元素、当前元素位置的最大和还有全部的最大和得到最大子序和。
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        lens = len(nums)
        temp = maxi = nums[0]
        for i in range(1, lens):
            temp = max(temp + nums[i], nums[i])
            maxi = max(maxi, temp)
        return maxi

2

  • 第三种:这个方法也不算是新思路,就是在第一种方法的基础上做了些改进,减少了代码量,复杂度仍然是O(n),所以运行速度上变化没有很大,而且受到点网络影响。但是这个思路也是简化了很多,我们只需要找到那个大于零的数字,然后往下找最大子序和就可以了,因为容易推理到,最大子序的第一个数字必须要大于零,所以这个方法也很简单,找到大于零的数然后往后一直试就好。
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        lens = len(nums)
        temp = maxi = nums[0]
        for i in range(1, lens):
            if temp > 0:
                temp = temp + nums[i]
            else:
                temp = nums[i]
            maxi = max(temp, maxi)
        return maxi

3

  • 第四种:分治法。我对这个方法其实不是特别了解,但是通过学习不同大佬的方法,我也尝试写了下。代码复杂度是O(nlogn),这个方法就是把数组分成三部分,要么最大子序在前半段,要么在后半段,要么就穿过中间。先通过递归的方法算出前半段和后半段的最大子序和,然后再计算中间的最大子序和,中间的这个也是先从中间到左边计算这段左半边的最大子序和,同理又计算右半边,然后加在一起就是中间的最大子序和。最后比较三个最大子序和的大小,求出整个数组的最大子序和。
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        lens = len(nums)
        maxi = nums[0]
        if lens == 1:
            return maxi
        else:
            maxi_left = self.maxSubArray(nums[0:lens // 2])
            maxi_right = self.maxSubArray(nums[lens // 2 : lens])
        maxi_1 = nums[lens // 2 - 1]
        temp = 0
        for i in range(lens // 2 - 1, -1, -1):
            temp += nums[i]
            maxi_1 = max(temp, maxi_1)
        maxi_2 = nums[lens // 2]
        temp = 0
        for i in range(lens // 2, lens):
            temp += nums[i]
            maxi_2 = max(temp, maxi_2)
        maxi = maxi_1 + maxi_2
        return max(maxi_left, maxi_right, maxi)

4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值