The min-product of an array is equal to the minimum value in the array multiplied by the array’s sum.
For example, the array [3,2,5] (minimum value is 2) has a min-product of 2 * (3+2+5) = 2 * 10 = 20.
Given an array of integers nums, return the maximum min-product of any non-empty subarray ofnums. Since the answer may be large, return it modulo10^9 + 7.
Note that the min-product should be maximized before performing the modulo operation. Testcases are generated such that the maximum min-product without modulo will fit in a 64-bit signed integer.
For each min product of subarray, we need min element in subarray and sum of all element.
We can quickly know the sum of an subarray with prefix sum array. The difficult point is how to get the min value for each array very quickly.
If we use Segment Tree, but this still O(N^2), since you will find for each pair of [i, j]. So, that is out of picture.
We can focus on each number in nums, let it be the min and we expand from this number to right and to left. We want to ask what is the first number on the right that is smaller than this number, and what is the first number on the left that is smaller than this number
Here is the approach:
Prefix Sum:
Use a prefix sum array to efficiently calculate the sum of any subarray.
Monotonic Stack:
Use a monotonic stack to find the nearest smaller elements to the left and right of each element.
This helps in identifying the subarray where the current element is the minimum.
Calculate Min-Product:
For each element, consider it as the minimum of a subarray.
Use the prefix sum array to quickly calculate the sum of this subarray.
Calculate the min-product and keep track of the maximum min-product found.
publicclassSolution {
publicintmaxSumMinProduct(int[] nums) {
int n = nums.length;
long[] prefixSum =newlong[n + 1];
long mod = 1_000_000_007;
// Build prefix sum arrayfor (int i = 0; i < n; i++) {
prefixSum[i + 1]= prefixSum[i]+ nums[i];
}
// Arrays to store the nearest smaller elements to the left and rightint[] left =newint[n];
int[] right =newint[n];
Arrays.fill(left, -1);
Arrays.fill(right, n);
Deque<Integer> stack =new ArrayDeque<>();
// Find nearest smaller to the leftfor (int i = 0; i < n; i++) {
while (!stack.isEmpty() && nums[stack.peek()]>= nums[i]) {
stack.pop();
}
if (!stack.isEmpty()) {
left[i]= stack.peek();
}
stack.push(i);
}
stack.clear();
// Find nearest smaller to the rightfor (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && nums[stack.peek()]>= nums[i]) {
stack.pop();
}
if (!stack.isEmpty()) {
right[i]= stack.peek();
}
stack.push(i);
}
// Calculate the maximum min-productlong maxMinProduct = 0;
for (int i = 0; i < n; i++) {
int l = left[i]+ 1;
int r = right[i]- 1;
long sum = prefixSum[r + 1]- prefixSum[l];
long minProduct = sum * nums[i];
maxMinProduct = Math.max(maxMinProduct, minProduct);
}
return (int)(maxMinProduct % mod);
}
publicstaticvoidmain(String[] args) {
Solution sol =new Solution();
int[] nums1 = {1, 2, 3, 2};
System.out.println(sol.maxSumMinProduct(nums1)); // Expected output: 14int[] nums2 = {2, 3, 3, 1, 2};
System.out.println(sol.maxSumMinProduct(nums2)); // Expected output: 18 }
}
classSolution:
defmaxSumMinProduct(self, nums: List[int]) -> int:
n = len(nums)
mod =10**9+7# Build prefix sum array prefix_sum = [0] * (n +1)
for i in range(n):
prefix_sum[i +1] = prefix_sum[i] + nums[i]
# Arrays to store the nearest smaller elements to the left and right left = [-1] * n
right = [n] * n
# Find nearest smaller to the left stack = []
for i in range(n):
while stack and nums[stack[-1]] >= nums[i]:
stack.pop()
if stack:
left[i] = stack[-1]
stack.append(i)
# Find nearest smaller to the right stack = []
for i in range(n-1, -1, -1):
while stack and nums[stack[-1]] >= nums[i]:
stack.pop()
if stack:
right[i] = stack[-1]
stack.append(i)
# Calculate the maximum min-product max_min_product =0for i in range(n):
l = left[i] +1 r = right[i] -1 total = prefix_sum[r +1] - prefix_sum[l]
min_product = total * nums[i]
max_min_product = max(max_min_product, min_product)
return max_min_product % mod
⏰ Time complexity: O(n), where n is the number of elements in the array. This is because we traverse the array a constant number of times to build the prefix sum, find the nearest smaller elements, and calculate the min-product.
🧺 Space complexity: O(n), for storing the prefix sum array and stacks.