📅  最后修改于: 2023-12-03 15:26:12.181000             🧑  作者: Mango
给定一个整数数组,找到两个连续子数组,使两个子数组的元素之和最大,并且这两个子数组的乘积也最大。返回乘积。
输入: [2,3,-2,4]
输出: 6
解释: 子数组为 [2,3] 和 [4],其乘积为 6。
首先思考如何求两个连续子数组之和的最大值。这个可以使用动态规划的思想。具体做法是用两个 dp 数组,一个记录到目前为止最大的子数组和,一个记录到目前为止最小的子数组和。每次更新时,要同时更新这两个 dp 数组。
假设要求的两个子数组为 A 和 B,它们的长度分别为 lA 和 lB。我们先在 A 和 B 中选取一个子数组,然后在剩下的数组中选取另一个子数组。假设我们选中了 A,那么剩下数组中最大子数组和是 la,最小子数组和是 lb。同理,如果选中了 B,则剩下数组中最大子数组和是 ra,最小子数组和是 rb。则答案就是 max((sumA - la) * (sumB - rb), (sumA - lb) *(sumB - ra))。
class Solution:
def maxProduct(self, nums: List[int]) -> int:
def maxSubArray(nums: List[int]) -> int:
max_sum = nums[0]
min_sum = nums[0]
ans = nums[0]
for i in range(1, len(nums)):
mx, mn = max_sum, min_sum
max_sum = max(mx+nums[i], nums[i], mn+nums[i])
min_sum = min(mx+nums[i], nums[i], mn+nums[i])
ans = max(ans, max_sum)
return ans
a, b = maxSubArray(nums), maxSubArray(nums[::-1])
nums.reverse()
for i in range(1, len(nums)):
nums[i] *= nums[i-1]
return max(a * maxSubArray(nums), b * maxSubArray(nums[::-1]))
假设数组长度为 n,则计算子数组和的时间复杂度为 O(n)。一次遍历中,需要计算两个子数组的最大值和最小值,时间复杂度均为 O(n),所以总的时间复杂度为 O(n)。
使用了常数个变量,所以空间复杂度为 O(1)。