Minimize Array sum by replacing elements such that Relation among adjacent elements in maintained
Given an array arr[] of size N, the task is to minimize the array sum after replacing array elements with positive integers in a way such the relation among the adjacent elements (pattern of the array)is maintained.
Note: If arr[i] = arr[i+1] then in the new array they both can be the same or one can be smaller than the other.
Examples:
Input: arr[] = [ 2, 1, 3]
Output: 5
Explanation: The redesigned array will be [2, 1, 2]. Sum = 5
Here arr[0] > arr[1] and arr[1] < arr[2] i.e. the relation among adjacent elements is unchanged.
This is the minimum sum possible after replacementsInput: arr[] = [ 4, 5, 5]
Output: 4
Explanation: We can redesign array as [1, 2, 1].
arr[0] < arr[1] and arr[1] >= arr[2] which satisfies the condition of the question.
So the minimum possible sum is 1+2+1 = 4
Approach: This problem can be solved based on the following observation:
- All the elements which are equal to or less than both its previous and next elements can be replaced by the smallest value i.e 1.
- The smallest possible value for an element is dependent on the number of contiguous smaller elements in its left (say X) and in its right (say Y). So the smallest possible value is maximum between X+1 and Y+1.
Follow the steps mentioned below to solve the problem
- Declare an array (say ans[]) to store the newly formed array after replacement and initialize all elements with 1.
- Traverse arr[] from i = 1 to N-1.
- If arr[i] > arr[i-1], then set ans[i] to be ans[i-1] +1 because this sets the array element to have the value of number of contiguous smaller elements on left of arr[i].
- Now traverse the array arr[] from i = N-2 to 0.
- If arr[i] > arr[i + 1], then set ans[i] to be max(ans[i+1] +1, ans[i]) because it sets the element to have value of the maximum number of contiguous elements on any side.
- Return the sum of the newly formed array i.e ans[].
Below is the implementation of the above approach:
C++
// C++ program for above approach #include <bits/stdc++.h> using namespace std; int marks(vector< int >& A) { // Making vector v and assigning 1 // to all elements vector< int > ans(A.size(), 1); // Traversing to check from left // If element is of higher value we will // add 1 to previous element for ( int i = 1; i < A.size(); i++) if (A[i] > A[i - 1]) ans[i] = ans[i - 1] + 1; // Traversing from right we will check // whether it has value satisfying both // side If element is of higher value we // will add 1 to previous element for ( int i = A.size() - 2; i >= 0; i--) if (A[i] > A[i + 1]) ans[i] = max(ans[i], ans[i + 1] + 1); // Accumulating the array // and returning the sum int sum = 0; for ( int s : ans) sum += s; return sum; } // Driver code int main() { // Initializing a vector vector< int > arr = { 4, 5, 5 }; // Function call cout << marks(arr) << endl; return 0; } |
Java
// Java program for above approach import java.io.*; class GFG { static int marks( int A[]) { // Making vector v and assigning 1 // to all elements int [] ans = new int [A.length]; for ( int i = 0 ; i < A.length; i++) ans[i] = 1 ; // Traversing to check from left // If element is of higher value we will // add 1 to previous element for ( int i = 1 ; i < A.length; i++) if (A[i] > A[i - 1 ]) ans[i] = ans[i - 1 ] + 1 ; // Traversing from right we will check // whether it has value satisfying both // side If element is of higher value we // will add 1 to previous element for ( int i = A.length - 2 ; i >= 0 ; i--) if (A[i] > A[i + 1 ]) ans[i] = Math.max(ans[i], ans[i + 1 ] + 1 ); // Accumulating the array // and returning the sum int sum = 0 ; for ( int i = 0 ; i < A.length; i++) sum += ans[i]; return sum; } // Driver code public static void main (String[] args) { // Initializing a vector int arr[] = { 4 , 5 , 5 }; // Function call System.out.println(marks(arr)); } } // This code is contributed by hrithikgarg03188. |
Python3
# Python program for above approach def marks(A): # Making vector v and assigning 1 # to all elements ans = [ 1 for i in range ( len (A))] # Traversing to check from left # If element is of higher value we will # add 1 to previous element for i in range ( 1 , len (A)): if (A[i] > A[i - 1 ]): ans[i] = ans[i - 1 ] + 1 # Traversing from right we will check # whether it has value satisfying both # side If element is of higher value we # will add 1 to previous element for i in range ( len (A) - 2 , - 1 , - 1 ): if (A[i] > A[i + 1 ]): ans[i] = max (ans[i],ans[i + 1 ] + 1 ) # Accumulating the array # and returning the sum sum = 0 for s in ans: sum + = s return sum # Driver code # Initializing a vector arr = [ 4 , 5 , 5 ] # Function call print (marks(arr)) # This code is contributed by shinjanpatra |
C#
// C# program for above approach using System; public class GFG { static int marks( int [] A) { // Making an array ans and assigning 1 // to all elements int [] ans = new int [A.Length]; for ( int i = 0; i < A.Length; i++) ans[i] = 1; // Traversing to check from left // If element is of higher value we will // add 1 to previous element for ( int i = 1; i < A.Length; i++) if (A[i] > A[i - 1]) ans[i] = ans[i - 1] + 1; // Traversing from right we will check // whether it has value satisfying both // side If element is of higher value we // will add 1 to previous element for ( int i = A.Length - 2; i >= 0; i--) if (A[i] > A[i + 1]) ans[i] = Math.Max(ans[i], ans[i + 1] + 1); // Accumulating the array // and returning the sum int sum = 0; for ( int i = 0; i < A.Length; i++) sum += ans[i]; return sum; } public static void Main( string [] args) { // Initializing a vector int [] arr = { 4, 5, 5 }; // Function call Console.Write(marks(arr)); } } // This code is contributed by phasing17 |
Javascript
<script> // JavaScript code for the above approach function marks(A) { // Making vector v and assigning 1 // to all elements let ans = new Array(A.length).fill(1); // Traversing to check from left // If element is of higher value we will // add 1 to previous element for (let i = 1; i < A.length; i++) if (A[i] > A[i - 1]) ans[i] = ans[i - 1] + 1; // Traversing from right we will check // whether it has value satisfying both // side If element is of higher value we // will add 1 to previous element for (let i = A.length - 2; i >= 0; i--) if (A[i] > A[i + 1]) ans[i] = Math.max(ans[i], ans[i + 1] + 1); // Accumulating the array // and returning the sum let sum = 0; for (let s of ans) sum += s; return sum; } // Driver code // Initializing a vector let arr = [4, 5, 5]; // Function call document.write(marks(arr) + '<br>' ); // This code is contributed by Potta Lokesh </script> |
4
Time Complexity: O(N)
Auxiliary Space: O(N)
Contact Us