LC 5752. 子数组最小乘积的最大值
https://leetcode-cn.com/problems/maximum-subarray-min-product/
这题的思路是,针对每个元素,假设这个元素是最小值,那么它所能覆盖的最大区间是什么。
这个寻找最大区间有点类似于构建find-union结构,我们以A[i]寻找最左侧点为例
- j = i - 1
- 假设A[i] > A[j]的话,那么最左侧点就是 j+1
- 如果A[i] <= A[j] 的话,那么最左侧点必然在 left[j] 更左侧
- j = left[j] - 1, 跳转到步骤2继续寻找
这个时间复杂度不太好确认,但是方法上似乎和find-union结构相近,并且有路径压缩,所以猜想时间复杂度是反ack函数 https://en.wikipedia.org/wiki/Ackermann_function#Inverse
class Solution:
def maxSumMinProduct(self, nums: List[int]) -> int:
n = len(nums)
left = [-1] * n
right = [-1] * n
left[0] = 0
right[-1] = n - 1
for i in range(1, n):
x = nums[i]
j = i - 1
while j >= 0 and x <= nums[j]:
j = left[j] - 1
left[i] = j + 1
for i in reversed(range(n - 1)):
x = nums[i]
j = i + 1
while j < n and x <= nums[j]:
j = right[j] + 1
right[i] = j - 1
acc = [0] * (n + 1)
for i in range(n):
acc[i + 1] = nums[i]
for i in range(n):
acc[i + 1] += acc[i]
left[0] = 0
right[-1] = n - 1
ans = 0
for i in range(n):
l, r = left[i], right[i]
x = nums[i]
acc2 = acc[r + 1] - acc[l]
m = x * acc2
ans = max(ans, m)
# print(m)
MOD = 10 ** 9 + 7
return ans % MOD