Maximum Subarray

这道题是Leetcode#53。个人觉得它很烦人。首先,看题不清楚的话,就变成找max和second max相加了。
那在找dynamic programming的公式的时候,也不好找。
总而言之,对我来说,我觉得很烦恼,觉得它不属于easy的那种。easy的那种应该是比较直接的。当然也许medium和hard更难就对了。
我是先在DP方面想,然后觉得nums[i:j]应该是可以从nums[i:j-1]和nums[i+1,j]之间推倒出来。结果搞错了,虽然搞了个蛋疼的2维数组,除了学习和练习Python的二维数组之外没什么用。浪费时间和空间。在超长的输入面前就超时了。

# 费时费力的代码如下,千万不要模仿!!
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:

        results = [[0 for j in range(len(nums))] for i in range(len(nums))]  # 这个还是不错的,虽然没有什么用

        max = nums[0]  # trick: let max be the first element
        results[0][0] = nums[0]
        for j in range(1, len(nums)):
            for i in range(j, -1, -1):
                if i == j:
                    results[i][j] = nums[i]
                else:
                    results[i][j] = nums[j] + results[i][j - 1]   #这里我把DP的公式搞错特了。

                if results[i][j] > max:    #这里我也想就着loop,一次把max找出来,不再单独循环了。
                    max = results[i][j]
        return max

结果发现一维的DP可以解决这个问题。我完全没有get it。故事的精髓是到第ith元素,如果前面的一串到i-1的数字之和是正数,那么对我是有用处的,我把它加上ith元素,就是我能组成的包括ith元素的maximum subarray。如果是负数或0,那么就没有什么用了,最大就是ith元素了。这个帖子讲的好清楚。https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:

        results = [0 for j in range(len(nums))]

        # trick: let max be the first element
        results[0] = nums[0]
        for i in range(1, len(nums)):
            if results[i-1] > 0:       # 这次就比较清楚了
                results[i] = nums[i] + results[i-1]
            else:
                results[i] = nums[i] # forget about the useless i-1 elements before me

        maxV = max(results)
        return maxV

那好,下面就是去掉DP的数组,因为我们只用到前面的一个,第i-1th。实际上这个值不需要用数组来特别保存的,只需要一个数。只有当DP用到前面的很多数的时候,才值得用数组把它们都存下来。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:

        # trick: let max be the first element
        results = nums[0]
        maxV = results
        for i in range(1, len(nums)):
            if results > 0:
                results = nums[i] + results
            else:
                results = nums[i] # forget about the useless i-1 elements before me
            # or in Python, one can write
            # results = max(nums[i], nums[i]+results)
            
            if results > maxV:
                maxV = results
            # or in Python
            # maxV = max(results, maxV)

        return maxV

这样一写,还是比较清楚哈。也许就是个EASY难度。思路不清醒还是不行。
题目作者还challenge大家用divide and conquer来解这道题,其实现在也是比较清楚了。

到ith元素(包含ith元素)的最优解是二选一:使用前i-1元素,不使用前i-1元素。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        
        def maxSubArrayHelper(nums: List[int]):
            if (len(nums) == 0):
                return (0,0)
        
            if (len(nums) == 1):
                return (nums[0],nums[0])         
        
            maxV, result = maxSubArrayHelper(nums[:len(nums)-1])
            
            result = max(nums[len(nums)-1]+result, nums[len(nums)-1])
            maxV = max(maxV, result)

            return (maxV, result)
        
        maxV, result = maxSubArrayHelper(nums)
        return maxV
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值