![]() |
VOOZH | about |
Given an array arr[] of integers of size N, the task is to maximize the sum of the array after removing valleys from the array when only reducing the value of an element is allowed i.e. the new formed array should not contain any element which has greater value after modification.
Valleys:- An index j is considered as a valley point if arr[i] > arr[j] and arr[ k ] > arr[ j ] given that (i < j < k).
Examples:
Input : arr[] = { 5, 10, 15 }
Output: 30
Explanation: As array does not contain any valley, so there is no need to reduce any element.
Input : arr[] = { 8, 1, 10, 1, 8 }
Output : 14
Explanation: new_arr=> [1, 1, 10, 1, 1] and sum = 14, new_arr can also be constructed as [8, 1, 1, 1, 1], but the sum will be less.
Naive Approach: Consider each element as a peak element and start in decreasing order in both directions of the peak element.
If arr = [8, 1, 10, 1, 8 ]
Consider 10 as peak element and then the final array would like [ 1, 1, 10, 1, 1]
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: Instead of taking each index as a peak point. Calculate prefix and suffix sum array for each index(idx). Prefix array can be used to store the sum of heights from 0 . . . idx satisfying the condition that there is no valley on the left side and idx has the peak element. Suffix sum array also satisfy the same conditions for the suffix of the index idx.
The element at an index can span in the left direction, till a smaller element is found, assuming that the current element is the highest one. The next smaller element using stack concept can be used here with minor changes.
Follow the steps mentioned below:
Note: arr[idx] is subtracted, because arr[ idx ] is added in left[] as well as right[] array.
See the illustration below for better understanding.
Illustration:
Consider the example arr[] = { 5, 1, 8 }
While building the prefix sum array
At index = 0: There is no element in the left[0] = 5.
Index = 1: 1 is the smallest among all from the left. So, left[1] = 1 * 2 = 2.
Index = 2: 8 has smaller element 1 at index 1. So left[2] = left[1] + 8*(2 - 1) = 2 + 8 = 10.
So left[] = {5, 2, 10}. Similarly right[] = {7, 2, 8}.
Now while traversing to calculate the answer the values from index 0, 1 and 2 are (5 + 7 - 5), (2 + 2 - 1), (10 + 8 - 8) respectively. The maximum among these is 10. So the answer is 10.
Below is the implementation of the above approach:
10
Time Complexity: O(N)
Auxiliary Space: O(N)