leetcode day4 ——Maximum subarray(要多看哦)

有四种解决方法:

  1. 直接暴力解决
  2. Kadane 算法
  3. 动态规划
  4. 分治算法

1、暴力解决
从头开始遍历整个数组中的数,并且进行组合,共有n(n+1)/2 种连续子数组,因此此选择方法需要的时间复杂度为O(n2)

2、Kadane 算法

  • 第i+1个数结尾的子列和= max(以第i个数结尾的子列和+nums[i+1],nums[i+1])
  • 使用递归 (迭代)从第一项开始计算得到每个i结尾的最大子列和
  • 比较得到最后的结果
class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        max_end_here = 0
        max_so_far = nums[0]
        for i in range(len(nums)):
            if max_end_here + nums[i] < nums[i]:
                max_end_here = nums[i]
            else:
                max_end_here += nums[i]
            if max_so_far < max_end_here:
                max_so_far  = max_end_here
        
        return max_so_far

来源:https://blog.csdn.net/the__apollo/article/details/77367534

3、分治的方法
这个问题可以分成三个子问题来思考,以中间为分界,求出左边的最大子序列和(max_left), 右边最大子序列和(max_right), 以及跨越中间的最大子序列和(max_cross).
跨越中间的最大子序列,可以使用挨着中间数(mid)左边的最大序列和加上挨着中间数(mid) 右边最大的序列和之和。
求着三个序列中的最大者则为最大子序列和。
整个算法的流程:

FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high):
left-sum = -inf
sum = 0
for i = mid downto low
    sum = sum + A[i]
    if sum > left-sum
        left-sum = sum
        max-left = i
        
right-sum = -inf
sum = 0
for j = mid+1 to high`在这里插入代码片`
    sum = sum + A[j]
    if sum > right-sum
        right-sum = sum
        max-right = i
        
return (max-left, max-right, left-sum+right+sum)

来源:https://www.cnblogs.com/jclian91/p/9151120.html

算法实现(拖了一个星期的我终于写完了我哭)

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length =len(nums) -1
        return self.maxsub(0, length, nums)
    
    def maxsub(self, lo, hi, nums):
        if hi < lo:
            return None
        if hi==lo:
            return nums[lo]
        if hi - lo == 1:
            return self.max_of_three(nums[lo], nums[hi]+nums[lo], nums[hi])
        mid = int((lo + hi)/2)
        max_l = self.maxsub(lo, mid, nums)
        max_r = self.maxsub(mid, hi, nums)
        max_cross = self.maxCross(lo, hi, mid, nums)
        return self.max_of_three(max_l, max_r, max_cross)
    
    def maxCross(self, lo, hi, mid, nums):
        i_l = i_r = mid
        v_l = v_r = nums[mid]
        v_l_tmp = v_r_tmp = nums[mid]
        while lo < i_l:
            v_l_tmp += nums[i_l-1]
            if v_l <= v_l_tmp:
                v_l = v_l_tmp
            i_l -= 1
        while i_r < hi:
            v_r_tmp += nums[i_r+1]
            if v_r <= v_r_tmp:
                v_r = v_r_tmp
            i_r += 1
        return self.max_of_three(v_l, v_l + v_r-nums[mid], v_r)
    
    def max_of_three(self, l, mid, r):
        max_v = l
        if max_v < mid:
            max_v = mid
        if max_v < r:
            max_v = r
        return max_v
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值