Minimize the number of operations to make all the elements equal with given conditions

Last Updated : 21 Feb, 2022

Given an array arr[]. The task is to minimize the number of operations required to make all the elements in arr[] equal. It is allowed to replace any element in arr[] with any other element almost once. Find the minimum number of operations required to do so, in one operation take any suffix of arr[] and increment/decrement values in that suffix by 1

Examples 

Input: arr[] = {-1, 0, 2}
Output: 1
Explanation: Following are the operations done to make all the elements in arr[] to be equal. 
Initially, change the last element of array to 0, so arr[] = {-1, 0, 0}
Now, using the operation once on the suffix starting at arr2, which means arr2 and arr3 are decreased by 1 . Thus, making all elements of array -1.
Hence, the number of operations is 1. 

Input: arr[] = {-3, -5, -2, 1 }
Output : 4

 

Approach: This problem is implementation-based. Follow the steps below to solve the given problem.

  • Since, it is not required to do any operation on suffix starting at arr1, since that can change all integers in the array.
  • So, the only way to make arri equal to arri-1 is to perform an operation on suffix starting at ai,  abs(ai−ai-1) times.
  • Now, the optimal way to initially change a value in the array is to minimize the operations.
  • In order to make arr1 equal to arr2, minimum operations are decreased by abs (arr2 - arr1).
  • Similarly, for making arrn equal to arrn-1, operation = abs(arrn - arrn-1).
  • For left elements, changing any element arri , affects both abs(ai−ai-1) and abs(ai+1−ai).
  • Also, observe this important fact that this value is minimized, when ai is between ai-1 and ai+1, inclusive.
  • Thus, number of operations is decreased from abs(ai−ai-1)+abs(ai+1−ai)  to abs(ai+1−ai-1).
  • Return the final answer.

Below is the implementation of the above approach:

C++
// C++ program for above approach
#include <bits/stdc++.h>
using namespace std;

void findMinOperations(vector<int> ar, int n)
{

    // Initializing vector to avoid overflows
    vector<int> arr(n + 5);

    for (int i = 1; i <= n; i++) {
        arr[i] = ar[i - 1];
    }
    int result = 0;

    // Calculating minimum operations to be
    // performed on initial array
    for (int i = 2; i <= n; i++) {
        result += abs(arr[i] - arr[i - 1]);
    }

    // Way to change a value to make
    // a1 equal to a2 or a(n)
    // equal to a(n-1)
    int max_operations
        = max(abs(arr[1] - arr[2]),
              abs(arr[n] - arr[n - 1]));
    for (int i = 2; i < n; i++) {

        // For the rest of elements
        // taking the max of
        // operations already done +
        // the ones performed here
        max_operations
            = max(
                max_operations,
                abs(arr[i] - arr[i - 1])
                    + abs(arr[i + 1] - arr[i])
                    - abs(arr[i + 1] - arr[i - 1]));
    }

    // Print the final result
    cout << result - max_operations << "\n";
}

// Driver Code
int main()
{

    int N = 3;
    vector<int> arr = { -1, 0, 2 };
    findMinOperations(arr, N);
    return 0;
}
Java
// Java program for above approach
class GFG {

  static void findMinOperations(int[] ar, int n) {

    // Initializing vector to avoid overflows
    int[] arr = new int[n + 5];

    for (int i = 1; i <= n; i++) {
      arr[i] = ar[i - 1];
    }
    int result = 0;

    // Calculating minimum operations to be
    // performed on initial array
    for (int i = 2; i <= n; i++) {
      result += Math.abs(arr[i] - arr[i - 1]);
    }

    // Way to change a value to make
    // a1 equal to a2 or a(n)
    // equal to a(n-1)
    int max_operations = Math.max(Math.abs(arr[1] - arr[2]),
                                  Math.abs(arr[n] - arr[n - 1]));
    for (int i = 2; i < n; i++) {

      // For the rest of elements
      // taking the max of
      // operations already done +
      // the ones performed here
      max_operations = Math.max(
        max_operations,
        Math.abs(arr[i] - arr[i - 1])
        + Math.abs(arr[i + 1] - arr[i])
        - Math.abs(arr[i + 1] - arr[i - 1]));
    }

    // Print the final result
    System.out.println(result - max_operations);
  }

  // Driver Code
  public static void main(String args[]) {

    int N = 3;
    int[] arr = { -1, 0, 2 };
    findMinOperations(arr, N);
  }
}

// This code is contributed by saurabh_jaiswal.
Python3
# Python code for the above approach
def findMinOperations(ar, n):

    # Initializing vector to avoid overflows
    arr = [0] * (n + 5)

    for i in range(1, n + 1):
        arr[i] = ar[i - 1]

    result = 0

    # Calculating minimum operations to be
    # performed on initial array
    for i in range(2, n + 1):
        result += abs(arr[i] - arr[i - 1])

    # Way to change a value to make
    # a1 equal to a2 or a(n)
    # equal to a(n-1)
    max_operations = max(abs(arr[1] - arr[2]), abs(arr[n] - arr[n - 1]))
    for i in range(2, n):

        # For the rest of elements
        # taking the max of
        # operations already done +
        # the ones performed here
        max_operations = max(
            max_operations,
            abs(arr[i] - arr[i - 1])
            + abs(arr[i + 1] - arr[i])
            - abs(arr[i + 1] - arr[i - 1]))

    # Print the final result
    print((result - max_operations))

# Driver Code
N = 3
arr = [-1, 0, 2]
findMinOperations(arr, N)

# This code is contributed by gfgking
C#
// C# program to implement
// the above approach
using System;

class GFG
{

  static void findMinOperations(int[] ar, int n) {

    // Initializing vector to avoid overflows
    int[] arr = new int[n + 5];

    for (int i = 1; i <= n; i++) {
      arr[i] = ar[i - 1];
    }
    int result = 0;

    // Calculating minimum operations to be
    // performed on initial array
    for (int i = 2; i <= n; i++) {
      result += Math.Abs(arr[i] - arr[i - 1]);
    }

    // Way to change a value to make
    // a1 equal to a2 or a(n)
    // equal to a(n-1)
    int max_operations = Math.Max(Math.Abs(arr[1] - arr[2]),
                                  Math.Abs(arr[n] - arr[n - 1]));
    for (int i = 2; i < n; i++) {

      // For the rest of elements
      // taking the max of
      // operations already done +
      // the ones performed here
      max_operations = Math.Max(
        max_operations,
        Math.Abs(arr[i] - arr[i - 1])
        + Math.Abs(arr[i + 1] - arr[i])
        - Math.Abs(arr[i + 1] - arr[i - 1]));
    }

    // Print the final result
    Console.Write(result - max_operations);
  }

  // Driver Code
  public static void Main()
  {
    int N = 3;
    int[] arr = { -1, 0, 2 };
    findMinOperations(arr, N);
  }
}

// This code is contributed by sanjoy_62.
JavaScript
 <script>
        // JavaScript code for the above approach 
        function findMinOperations(ar, n) {

            // Initializing vector to avoid overflows
            let arr = new Array(n + 5);

            for (let i = 1; i <= n; i++) {
                arr[i] = ar[i - 1];
            }
            let result = 0;

            // Calculating minimum operations to be
            // performed on initial array
            for (let i = 2; i <= n; i++) {
                result += Math.abs(arr[i] - arr[i - 1]);
            }

            // Way to change a value to make
            // a1 equal to a2 or a(n)
            // equal to a(n-1)
            let max_operations
                = Math.max(Math.abs(arr[1] - arr[2]),
                    Math.abs(arr[n] - arr[n - 1]));
            for (let i = 2; i < n; i++) {

                // For the rest of elements
                // taking the max of
                // operations already done +
                // the ones performed here
                max_operations
                    = Math.max(
                        max_operations,
                        Math.abs(arr[i] - arr[i - 1])
                        + Math.abs(arr[i + 1] - arr[i])
                        - Math.abs(arr[i + 1] - arr[i - 1]));
            }

            // Print the final result
            document.write((result - max_operations) + "</br>");
        }

        // Driver Code
        let N = 3;
        let arr = [-1, 0, 2];
        findMinOperations(arr, N);

       // This code is contributed by Potta Lokesh
    </script>

Output
1

Time complexity: O(N) 
Auxiliary Space: O(1)

Comment