Minimum operations of given type to make all elements of a matrix equal

Given an integer K and a matrix of N rows and M columns, the task is to find the minimum number of operations required to make all the elements of the matrix equal. In a single operation, K can be added to or subtracted from any element of the matrix. Print -1 if it is impossible to do so.
Examples: 

Input: mat[][] = {{2, 4}, {22, 24}}, K = 2 
Output: 20 
mat[0][0] = 2 + (10 * K) = 22 … 10 operations 
mat[0][1] = 4 + (9 * K) = 22 … 9 operations 
mat[1][0] = 22 … No operation 
mat[1][1] = 24 – K = 22 … 1 operations 
10 + 9 + 1 = 20 
Input: mat[][] = { 
{3, 63, 42}, 
{18, 12, 12}, 
{15, 21, 18}, 
{33, 84, 24}}, 
K = 3 
Output: 63 

Approach: Since we are only allowed to add or subtract K from any element, we can easily infer that mod of all the elements with K should be equal because x % K = (x + K) % K = (x – K) % K
If that is not the case simply print -1. Else, sort all the elements of the matrix in non-deceasing order and find the median of the sorted elements. The minimum number of steps would occur if we convert all the elements equal to the median. Calculate these steps and print the result.
Below is the implementation of the above approach: 
 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the minimum
// number of operations required
int minOperations(int n, int m, int k,
                  vector<vector<int> >& matrix)
{
    // Create another array to
    // store the elements of matrix
    vector<int> arr(n * m, 0);
 
    int mod = matrix[0][0] % k;
 
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            arr[i * m + j] = matrix[i][j];
 
            // If not possible
            if (matrix[i][j] % k != mod) {
                return -1;
            }
        }
    }
 
    // Sort the array to get median
    sort(arr.begin(), arr.end());
 
    int median = arr[(n * m) / 2];
 
    // To count the minimum operations
    int minOperations = 0;
    for (int i = 0; i < n * m; ++i)
        minOperations += abs(arr[i] - median) / k;
 
    // If there are even elements, then there
    // are two medians. We consider the best
    // of two as answer.
    if ((n * m) % 2 == 0)
    {
       int median2 = arr[(n * m) / 2];
       int minOperations2 = 0;
       for (int i = 0; i < n * m; ++i)
          minOperations2 += abs(arr[i] - median2) / k;
 
       minOperations = min(minOperations, minOperations2);
    }
 
    // Return minimum operations required
    return minOperations;
}
 
// Driver code
int main()
{
    vector<vector<int> > matrix = { { 2, 4, 6 },
                                    { 8, 10, 12 },
                                    { 14, 16, 18 },
                                    { 20, 22, 24 } };
    int n = matrix.size();
    int m = matrix[0].size();
    int k = 2;
    cout << minOperations(n, m, k, matrix);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
 
class GFG
{
    // Function to return the minimum
    // number of operations required
    static int minOperations(int n, int m,
                        int k, int matrix[][])
    {
        // Create another array to
        // store the elements of matrix
        int [] arr = new int[n * m];
     
        int mod = matrix[0][0] % k;
     
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                arr[i * m + j] = matrix[i][j];
     
                // If not possible
                if (matrix[i][j] % k != mod)
                {
                    return -1;
                }
            }
        }
     
        // Sort the array to get median
        Arrays.sort(arr);
     
        int median = arr[(n * m) / 2];
     
        // To count the minimum operations
        int minOperations = 0;
        for (int i = 0; i < n * m; ++i)
            minOperations += Math.abs(arr[i] - median) / k;
     
        // If there are even elements, then there
        // are two medians. We consider the best
        // of two as answer.
        if ((n * m) % 2 == 0)
        {
        int median2 = arr[(n * m) / 2];
        int minOperations2 = 0;
        for (int i = 0; i < n * m; ++i)
            minOperations2 += Math.abs(arr[i] - median2) / k;
 
        minOperations = Math.min(minOperations, minOperations2);
        }
     
        // Return minimum operations required
        return minOperations;
    }
     
    // Driver code
    public static void main(String []args)
    {
        int matrix [][] = { { 2, 4, 6 },
                            { 8, 10, 12 },
                            { 14, 16, 18 },
                            { 20, 22, 24 } };
                             
        int n = matrix.length;
        int m = matrix[0].length;
        int k = 2;
        System.out.println(minOperations(n, m, k, matrix));
    }
}
 
// This code is contributed by ihritik
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
 
# Function to return the minimum
# number of operations required
def minOperations(n, m, k, matrix):
 
    # Create another array to store the
    # elements of matrix
    arr = [0] * (n * m)
 
    mod = matrix[0][0] % k
 
    for i in range(0, n):
        for j in range(0, m):
            arr[i * m + j] = matrix[i][j]
 
            # If not possible
            if matrix[i][j] % k != mod:
                return -1
 
    # Sort the array to get median
    arr.sort()
 
    median = arr[(n * m) // 2]
 
    # To count the minimum operations
    minOperations = 0
    for i in range(0, n * m):
        minOperations += abs(arr[i] - median) // k
 
    # If there are even elements, then there
    # are two medians. We consider the best
    # of two as answer.
    if (n * m) % 2 == 0:
     
        median2 = arr[(n * m) // 2]
        minOperations2 = 0
        for i in range(0, n * m):
            minOperations2 += abs(arr[i] - median2) // k
 
        minOperations = min(minOperations,
                            minOperations2)
     
    # Return minimum operations required
    return minOperations
 
# Driver code
if __name__ == "__main__":
 
    matrix = [[2, 4, 6],
              [8, 10, 12],
              [14, 16, 18],
              [20, 22, 24]]
             
    n = len(matrix)
    m = len(matrix[0])
    k = 2
    print(minOperations(n, m, k, matrix))
 
# This code is contributed by Rituraj Jain
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
 
class GFG
{
    // Function to return the minimum
    // number of operations required
    static int minOperations(int n, int m,
                        int k, int [,]matrix)
    {
         
        // Create another array to
        // store the elements of matrix
        int []arr = new int[n * m];
     
        int mod = matrix[0, 0] % k;
     
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                arr[i * m + j] = matrix[i,j];
     
                // If not possible
                if (matrix[i,j] % k != mod)
                {
                    return -1;
                }
            }
        }
     
        // Sort the array to get median
        Array.Sort(arr);
     
        int median = arr[(n * m) / 2];
     
        // To count the minimum operations
        int minOperations = 0;
        for (int i = 0; i < n * m; ++i)
            minOperations += Math.Abs(arr[i] - median) / k;
     
        // If there are even elements, then there
        // are two medians. We consider the best
        // of two as answer.
        if ((n * m) % 2 == 0)
        {
            int median2 = arr[(n * m) / 2];
            int minOperations2 = 0;
            for (int i = 0; i < n * m; ++i)
                minOperations2 += Math.Abs(arr[i] - median2) / k;
 
            minOperations = Math.Min(minOperations, minOperations2);
        }
     
        // Return minimum operations required
        return minOperations;
    }
     
    // Driver code
    public static void Main()
    {
        int [,]matrix = { { 2, 4, 6 },
                            { 8, 10, 12 },
                            { 14, 16, 18 },
                            { 20, 22, 24 } };
                             
        int n = matrix.GetLength(0);
        int m = matrix.GetLength(1);
        int k = 2;
        Console.WriteLine(minOperations(n, m, k, matrix));
    }
}
 
// This code is contributed by Ryuga
chevron_right

Output: 
36



 

Below is an implementation that handles negative numbers also in the input matrix : 
 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the minimum
// number of operations required
int minOperations(int n, int m, int k,
                  vector<vector<int> >& matrix)
{
    // Create another array to
    // store the elements of matrix
    vector<int> arr;
 
    int mod;
     
    // will not work for negative elements, so ..
    // adding this
    if (matrix[0][0] < 0) {
        mod = k - (abs(matrix[0][0]) % k);
    }
    else {
        mod = matrix[0][0] % k;
    }
     
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            arr.push_back(matrix[i][j]);
 
            // adding this to handle negative elements too .
            int val = matrix[i][j];
            if (val < 0) {
                int res = k - (abs(val) % k);
                if (res != mod) {
                    return -1;
                }
            }
            else {
                int foo = matrix[i][j];
                if (foo % k != mod) {
                    return -1;
                }
            }
        }
    }
 
    // Sort the array to get median
    sort(arr.begin(), arr.end());
 
    int median = arr[(n * m) / 2];
 
    // To count the minimum operations
    int minOperations = 0;
    for (int i = 0; i < n * m; ++i)
        minOperations += abs(arr[i] - median) / k;
 
    // If there are even elements, then there
    // are two medians. We consider the best
    // of two as answer.
    if ((n * m) % 2 == 0) {
 
        // changed here as in case of even elements there will be 2 medians
        int median2 = arr[((n * m) / 2) - 1];
 
        int minOperations2 = 0;
        for (int i = 0; i < n * m; ++i)
            minOperations2 += abs(arr[i] - median2) / k;
 
        minOperations = min(minOperations, minOperations2);
    }
 
    // Return minimum operations required
    return minOperations;
}
 
// Driver code
int main()
{
    vector<vector<int> > matrix = { { 2, 4, 6 },
                                    { 8, 10, 12 },
                                    { 14, 16, 18 },
                                    { 20, 22, 24 } };
    int n = matrix.size();
    int m = matrix[0].size();
    int k = 2;
    cout << minOperations(n, m, k, matrix);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the
# above approach
 
# Function to return the minimum
# number of operations required
def minOperations(n, m, k,
                  matrix):
 
    # Create another array to
    # store the elements of
    # matrix
    arr = []
 
    # will not work for negative
    # elements, so .. adding this
    if (matrix[0][0] < 0):
        mod = k - (abs(matrix[0][0]) % k)
    else:
        mod = matrix[0][0] % k
 
    for i in range(n):
        for j in range(m):
            arr.append(matrix[i][j])
 
            # adding this to handle
            # negative elements too .
            val = matrix[i][j]
             
            if (val < 0):
                res = k - (abs(val) % k)
                if (res != mod):
                    return -1
            else:
                foo = matrix[i][j]
                if (foo % k != mod):
                    return -1
 
    # Sort the array to get median
    arr.sort()
 
    median = arr[(n * m) // 2]
 
    # To count the minimum
    # operations
    minOperations = 0
    for i in range(n * m):
        minOperations += abs(arr[i] -
                             median) // k
 
    # If there are even elements,
    # then there are two medians.
    # We consider the best of two
    # as answer.
    if ((n * m) % 2 == 0):
 
        # changed here as in case of
        # even elements there will be
        # 2 medians
        median2 = arr[((n * m) //
                        2) - 1]
 
        minOperations2 = 0
        for i in range(n * m):
            minOperations2 += abs(arr[i] -
                                  median2) / k
             
        minOperations = min(minOperations,
                            minOperations2)
 
    # Return minimum operations required
    return minOperations
 
# Driver code
if __name__ == "__main__":
 
    matrix = [[2, 4, 6],
              [8, 10, 12],
              [14, 16, 18],
              [20, 22, 24]]
    n = len(matrix)
    m = len(matrix[0])
    k = 2
    print(minOperations(n, m, k, matrix))
 
# This code is contributed by Chitranayal
chevron_right

Output: 
36



 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





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.



Article Tags :