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++ 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 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. |
# 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# 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 |
<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)