Minimize increment/decrement of Array elements to make each modulo K equal

Given an array arr[] of length N and an integer K. In each operation any element(say arr[i]) can be selected from the array and can be changed to arr[i] + 1 or arr[i] – 1. The task is to find the minimum number of operation required to perform on array such that each value of the array modulo K remains same.
Examples: 
 

Input: arr[] = {4, 5, 8, 3, 12},  k =5
Output: 4
Explanation:
Operation 1: { 3, 5, 8, 3, 12 }, decrease 4 at index 0 by 1.
Operation 2: { 3, 4, 8, 3, 12 }, decrease 5 at index 1 by 1.
Operation 3: { 3, 3, 8, 3, 12 }, decrease 4 at index 1 by 1.
Operation 4: { 3, 3, 8, 3, 13 }, increase 12 at index 4 by 1.
The modulo of each number is equal to 3 and minimum steps required were 4.

Input: arr[] = {2, 35, 48, 23, 52},  k =3
Output: 2
Explanation:
Minimum number of steps required to make modulo of each number equal is 2.

Approach: The idea is to use Hashing that keeps the count of each modulo that has been obtained.

  • Now iterate for each value of i, in range 0 <= i < k, and find the number of operation required to make the modulo of all numbers equal.
  • If it is less than the value obtained than the currently stored value then update it.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the minimum operations
// required to make the modulo of each
// element of the array equal to each other
int Find_min(set<int>& diff_mod,
             map<int, int> count_mod, int k)
{
    // Variable to store minimum
    // operation required
    int min_oprn = INT_MAX;
  
    // To store operation required to
    // make all modulo equal
    int oprn = 0;
  
    // Iterating through all
    // possible modulo value
    for (int x = 0; x < k; x++) {
        oprn = 0;
  
        // Iterating through all different
        // modulo obtained so far
        for (auto w : diff_mod) {
  
            // Caculating oprn required
            // to make all modulos equal
            // to x
            if (w != x) {
  
                if (w == 0) {
  
                    // Checking the operations
                    // that will cost less
                    oprn += min(x, k - x)
                            * count_mod[w];
                }
  
                else {
  
                    // Check operation that
                    // will cost less
                    oprn += min(
                                abs(x - w),
                                k + x - w)
                            * count_mod[w];
                }
            }
        }
  
        // Update the minimum
        // number of operations
        if (oprn < min_oprn)
            min_oprn = oprn;
    }
  
    // Returing the answer
    return min_oprn;
}
  
// Function to store different modulos
int Cal_min(int arr[], int n, int k)
{
    // Set to store all
    // different modulo
    set<int> diff_mod;
  
    // Map to store count
    // of all different  modulo
    // obtained
    map<int, int> count_mod;
  
    // Storing all different
    // modulo count
    for (int i = 0; i < n; i++) {
  
        // Insert into the set
        diff_mod.insert(arr[i] % k);
  
        // Increment count
        count_mod[arr[i] % k]++;
    }
  
    // Function call to return value of
    // min oprn required
    return Find_min(diff_mod, count_mod, k);
}
  
// Driver Code
int main()
{
    int arr[] = { 2, 35, 48, 23, 52 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    cout << Cal_min(arr, n, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
  
class GFG{
      
// Function to find the minimum operations
// required to make the modulo of each
// element of the array equal to each other
static int Find_min(HashSet<Integer> diff_mod,
                    HashMap<Integer, 
                            Integer> count_mod,
                    int k)
{
      
    // Variable to store minimum
    // operation required
    int min_oprn = Integer.MAX_VALUE;
  
    // To store operation required to
    // make all modulo equal
    int oprn = 0;
  
    // Iterating through all
    // possible modulo value
    for(int x = 0; x < k; x++)
    {
        oprn = 0;
  
        // Iterating through all different
        // modulo obtained so far
        for(int w : diff_mod) 
        {
  
            // Caculating oprn required
            // to make all modulos equal
            // to x
            if (w != x) 
            {
                if (w == 0)
                {
                      
                    // Checking the operations
                    // that will cost less
                    oprn += Math.min(x, k - x) *
                            count_mod.get(w);
                }
                else 
                {
                      
                    // Check operation that
                    // will cost less
                    oprn += Math.min(Math.abs(x - w), 
                                     k + x - w) * 
                                     count_mod.get(w);
                }
            }
        }
  
        // Update the minimum
        // number of operations
        if (oprn < min_oprn)
            min_oprn = oprn;
    }
  
    // Returing the answer
    return min_oprn;
}
  
// Function to store different modulos
static int Cal_min(int arr[], int n, int k)
{
      
    // Set to store all
    // different modulo
    HashSet<Integer> diff_mod = new HashSet<>();
  
    // Map to store count
    // of all different modulo
    // obtained
    HashMap<Integer, 
            Integer> count_mod = new HashMap<>();
  
    // Storing all different
    // modulo count
    for(int i = 0; i < n; i++) 
    {
          
        // Insert into the set
        diff_mod.add(arr[i] % k);
  
        // Increment count
        count_mod.put(arr[i] % k, 
        count_mod.getOrDefault(arr[i] % k, 0) + 1);
    }
  
    // Function call to return value of
    // min oprn required
    return Find_min(diff_mod, count_mod, k);
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 2, 35, 48, 23, 52 };
    int n = arr.length;
    int k = 3;
      
    System.out.print(Cal_min(arr, n, k));
}
}
  
// This code is contributed by jrishabh99

chevron_right


Output: 

2

Time Complexity: O(N*K)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : jrishabh99