最大子序和/积

面试题42. 连续子数组的最大和

难度⭐

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

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

思路

贪心(选择使总和变大的)

  • 如果 之前和 小于0 ,当前数字 与 之前和 的和 会更小,所以选max(num,num+presum)

  • 如果当前数字 小于0 同时 之前和大于0 ,会导致总和减小,所以需要记录总和 max(presum,maxsum)

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        #贪心
        #如果当前和为负  会对总和造成负影响
        #如果当前和为正  当前数字为负 可能造成总和减小 所以需要记录总和
        if not nums:
            return 0
        presum,maxsum = float('-inf'),nums[0]
        for num in nums:
            presum = max(num,presum+num)
            maxsum = max(maxsum,cursum)
        return maxsum

动态规划

dp[i]记录前i个元素的最大和

  • 如果 dp[i-1]<0 会使总和减小,dp[i]=nums[i]
  • 如果 dp[i-1]>0 会使总和增加,dp[i]=nums[i]+dp[i-1]
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        #动态规划
        if not nums:
            return 0
        dp = [float('-inf')]*len(nums)
        dp[0] = nums[0]
        for i in range(1,len(nums)):
                dp[i] = nums[i]+dp[i-1] if dp[i-1]>0 else nums[i]
        return max(dp)

152. 乘积最大子数组

难度⭐⭐

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

示例 1:

输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

思路

借鉴上一题最大子序和的思想,记录目前为止所有元素的最大乘积

  • 但是在乘积会出现 负负得正 的情况,所以需要另外记录 最小乘积
  • 判断 当前数字 的正负
    • 如果为 负 ,maxsum = max(num, minsum*num)

coding

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        if not nums:
            return 0
        ans = float('-inf')
        maxsum,minsum = 1,1
        for num in nums:
            if num < 0:
                maxsum,minsum = minsum,maxsum
            maxsum = max(num,maxsum*num)
            minsum = min(num,minsum*num)
            ans = max(ans,maxsum)
        return ans
posted @ 2020-05-18 18:59  鱼与鱼  阅读(165)  评论(0编辑  收藏  举报