Open In App

Minimize Array sum by replacing elements such that Relation among adjacent elements in maintained

Last Updated : 21 Apr, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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 replacements

Input: 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>


Output

4

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads