Open In App

Making Row and Column Sums Equal

Last Updated : 03 Jul, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given a square matrix mat[][], determine the minimum number of operations required to make the sum of elements in each row and each column equal. In one operation, you are allowed to increment any individual cell by 1.

Examples: 

Input: mat[][] = [[1, 2],
[3, 4]]
Output: 4
Explanation: Increment value of cell (0, 0) 3 times. 
Increment value of cell (0, 1) 1 time.
Matrix after the operations: [[4, 3],
[3, 4]]
with sum of each row and column as 7. Hence total 4 operation are required.

Input: mat[][] = [[1, 2, 3],
[4, 2, 3],
[3, 2, 1]]
Output: 6
Explanation: Increment value of cell(0, 0) 1 time. 
Increment value of cell(0, 1) 2 times. 
Increment value of cell(2, 1) 1 time.
Increment value of cell(2, 2) 2 times.
Matrix after the operations: [[2, 4, 3],
[4, 2, 3],
[3, 3, 3]]
with sum of each row and column as 9. Hence total 6 operation are required.

[Naive Approach] Brute Force Simulation

The naive approach incrementally adjusts the matrix by always increasing the element at the intersection of the row and column with the minimum sums. This is repeated until all row and column sums become equal. It simulates the process step-by-step without optimization, leading to high time complexity.

Why it works:

  • The only way to increase both row and column sums simultaneously is to increment a single cell.
  • Since each increment increases one row and one column by 1, the most efficient strategy is to increase the lowest row and column simultaneously.
  • This greedy method ensures you're always choosing the best possible cell to move the whole matrix closer to a balanced state in each step.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int balanceSum(vector<vector<int>>& mat) {
    
    int n = mat.size();
    vector<int> rowSum(n, 0), colSum(n, 0);

    // Compute initial row and column sums
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j) {
            rowSum[i] += mat[i][j];
            colSum[j] += mat[i][j];
        }

    int operations = 0;

    // Repeat until all row and 
    // column sums become equal
    while (true) {
        
        // Find maximum row/col sum
        int maxSum = *max_element(rowSum.begin(),
                                            rowSum.end());
        maxSum = max(maxSum, *max_element(colSum.begin(),
                                            colSum.end()));

        bool done = true;

        for (int i = 0; i < n && done; ++i)
            if (rowSum[i] != maxSum || colSum[i] != maxSum)
                done = false;

        if (done) break;

        // Find row and column with the minimum sum
        int minRow = min_element(rowSum.begin(),
                        rowSum.end()) - rowSum.begin();
        int minCol = min_element(colSum.begin(),
                        colSum.end()) - colSum.begin();

        // Increment the element
        // at their intersection
        mat[minRow][minCol]++;
        rowSum[minRow]++;
        colSum[minCol]++;
        operations++;
    }

    return operations;
}

int main() {
    
    vector<vector<int>> mat = {
        {1, 2, 3},
        {4, 2, 3},
        {3, 2, 1}
    };

    cout << balanceSum(mat) << endl;

    return 0;
}
Java
import java.util.Arrays;

class GfG {

    static int balanceSum(int[][] mat) {
        int n = mat.length;
        int[] rowSum = new int[n];
        int[] colSum = new int[n];

        // Compute initial row and column sums
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j) {
                rowSum[i] += mat[i][j];
                colSum[j] += mat[i][j];
            }

        int operations = 0;

        // Repeat until all row and column sums become equal
        while (true) {
            
            // Find maximum row/col sum
            int maxRowSum = Arrays.stream(rowSum).max().getAsInt();
            int maxColSum = Arrays.stream(colSum).max().getAsInt();
            int maxSum = Math.max(maxRowSum, maxColSum);

            boolean done = true;

            for (int i = 0; i < n && done; ++i)
                if (rowSum[i] != maxSum || colSum[i] != maxSum)
                    done = false;

            if (done) break;

            // Find row and column with the minimum sum
            int minRow = 0, minCol = 0;
            for (int i = 1; i < n; ++i)
                if (rowSum[i] < rowSum[minRow]) minRow = i;

            for (int j = 1; j < n; ++j)
                if (colSum[j] < colSum[minCol]) minCol = j;

            // Increment the element at their intersection
            mat[minRow][minCol]++;
            rowSum[minRow]++;
            colSum[minCol]++;
            operations++;
        }

        return operations;
    }

    // Driver Code
    public static void main(String[] args) {
        int[][] mat = {
            {1, 2, 3},
            {4, 2, 3},
            {3, 2, 1}
        };

        System.out.println(balanceSum(mat));
    }
}
Python
def balanceSum(mat):
    n = len(mat)
    rowSum = [0] * n
    colSum = [0] * n

    # Compute initial row and column sums
    for i in range(n):
        for j in range(n):
            rowSum[i] += mat[i][j]
            colSum[j] += mat[i][j]

    operations = 0

    # Repeat until all row and column sums become equal
    while True:
        # Find maximum row/col sum
        maxSum = max(max(rowSum), max(colSum))

        done = all(rowSum[i] == maxSum and
                colSum[i] == maxSum for i in range(n))
        if done:
            break

        # Find row and column with the minimum sum
        minRow = rowSum.index(min(rowSum))
        minCol = colSum.index(min(colSum))

        # Increment the element at their intersection
        mat[minRow][minCol] += 1
        rowSum[minRow] += 1
        colSum[minCol] += 1
        operations += 1

    return operations

if __name__ == "__main__":
    mat = [
        [1, 2, 3],
        [4, 2, 3],
        [3, 2, 1]
    ]

    print(balanceSum(mat))
C#
using System;
using System.Linq;

class GfG
{
    static int balanceSum(int[,] mat)
    {
        int n = mat.GetLength(0);
        int[] rowSum = new int[n];
        int[] colSum = new int[n];

        // Compute initial row and column sums
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
            {
                rowSum[i] += mat[i, j];
                colSum[j] += mat[i, j];
            }

        int operations = 0;

        // Repeat until all row and column sums become equal
        while (true)
        {
            // Find maximum row/col sum
            int maxSum = Math.Max(rowSum.Max(), colSum.Max());

            bool done = true;
            for (int i = 0; i < n && done; ++i)
                if (rowSum[i] != maxSum || colSum[i] != maxSum)
                    done = false;

            if (done) break;

            // Find row and column with the minimum sum
            int minRow = 0, minCol = 0;
            for (int i = 1; i < n; ++i)
                if (rowSum[i] < rowSum[minRow]) minRow = i;
            for (int j = 1; j < n; ++j)
                if (colSum[j] < colSum[minCol]) minCol = j;

            // Increment the element at their intersection
            mat[minRow, minCol]++;
            rowSum[minRow]++;
            colSum[minCol]++;
            operations++;
        }

        return operations;
    }

    static void Main()
    {
        int[,] mat = {
            {1, 2, 3},
            {4, 2, 3},
            {3, 2, 1}
        };

        Console.WriteLine(balanceSum(mat));
    }
}
JavaScript
function balanceSum(mat) {
    const n = mat.length;
    const rowSum = new Array(n).fill(0);
    const colSum = new Array(n).fill(0);

    // Compute initial row and column sums
    for (let i = 0; i < n; ++i)
        for (let j = 0; j < n; ++j) {
            rowSum[i] += mat[i][j];
            colSum[j] += mat[i][j];
        }

    let operations = 0;

    // Repeat until all row and column sums become equal
    while (true) {
        
        // Find maximum row/col sum
        const maxSum = Math.max(Math.max(...rowSum),
                                    Math.max(...colSum));

        let done = true;
        for (let i = 0; i < n; ++i) {
            if (rowSum[i] !== maxSum || colSum[i] !== maxSum) {
                done = false;
                break;
            }
        }

        if (done) break;

        // Find row and column with the minimum sum
        const minRow = rowSum.indexOf(Math.min(...rowSum));
        const minCol = colSum.indexOf(Math.min(...colSum));

        // Increment the element at their intersection
        mat[minRow][minCol]++;
        rowSum[minRow]++;
        colSum[minCol]++;
        operations++;
    }

    return operations;
}


// Driver Code
const mat = [
        [1, 2, 3],
        [4, 2, 3],
        [3, 2, 1]
    ];

console.log(balanceSum(mat));

Output
6

Time Complexity: O(n2 * maxEleDiff) where maxEleDiff is the difference between the maximum and minimum sum values.
Auxiliary Space: O(n) for row and column sum arrays.

[Expected Approach] Max-Target Normalization - O(n^2) Time and O(1) Time

The idea is to equalize all row and column sums, so for that we will first compute: maxSum = max(maxRowSum, maxColSum).
We aim to make every row and column sum equal to maxSum. To do this, we increment elements only in rows and columns that fall short of maxSum, ensuring we never exceed maxSum for any row or column. Each increment at a cell (i, j) contributes to both the row and column sums.

Why this approach works

  • We only increase cells where both the row and column sums are less than maxSum .
  • This ensures that no row or column ever exceeds the target sum.
  • Every increment contributes to increasing the total matrix sum by 1.
  • We stop once the total matrix sum reaches n × maxSum.

At this point:

  • Each row sum ≤ maxSum, and total of all row sums = n × maxSum → so every row sum = maxSum.
  • Same holds for columns.

Thus, all rows and columns are exactly maxSum, and we've used the minimum number of operations:

minOperations = n × s – totalSum

C++
#include <iostream>
#include <vector>
using namespace std;

int balanceSums(vector<vector<int>> &mat) {
	int n = mat.size();
    int res = 0;
    int maxSum = 0;
  
    // find maximum sum across all rows
    for(int i = 0; i < n; i++) {
        int sum = 0;
        for(int j = 0; j < n; j++)
            sum += mat[i][j];
        maxSum = max(sum, maxSum);
    }
  
    // find maximum sum across all columns
    for(int j = 0; j < n; j++) {
        int sum = 0;
        for(int i = 0; i < n; i++)
            sum += mat[i][j];
        maxSum = max(sum, maxSum);
    }
    
    // sum of operations across all rows
    for(int i = 0; i < n; i++) {
        int sum = 0;
        for(int j = 0; j < n; j++) {
			sum += mat[i][j];
        }
        res += (maxSum - sum);
    }
    return res;
}

int main() {
    vector<vector<int>> mat =  
        {
          { 1, 2, 3 }, 
          { 4, 2, 3 }, 
          { 3, 2, 1 }
        };
                               
    cout << balanceSums(mat);
    return 0;
}
Java
import java.util.Arrays;

class GfG {
    static int balanceSum(int[][] mat) {
        int n = mat.length;
        int res = 0;
        int maxSum = 0;

        // Find maximum sum across all rows
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = 0; j < n; j++) {
                sum += mat[i][j];
            }
            maxSum = Math.max(sum, maxSum);
        }

        // Find maximum sum across all columns
        for (int j = 0; j < n; j++) {
            int sum = 0;
            for (int i = 0; i < n; i++) {
                sum += mat[i][j];
            }
            maxSum = Math.max(sum, maxSum);
        }

        // Sum of operations across all rows
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = 0; j < n; j++) {
                sum += mat[i][j];
            }
            res += (maxSum - sum);
        }
        return res;
    }

    public static void main(String[] args) {
        int[][] mat = {
            { 1, 2, 3 },
            { 4, 2, 3 },
            { 3, 2, 1 }
        };
        System.out.println(balanceSum(mat));
    }
}
Python
def balanceSum(mat):
    n = len(mat)
    res = 0
    maxSum = 0
    
    # Find maximum sum across all rows
    for i in range(n):
        sum = 0
        for j in range(n):
            sum += mat[i][j]
        maxSum = max(sum, maxSum)
    
    # Find maximum sum across all columns
    for j in range(n):
        sum = 0
        for i in range(n):
            sum += mat[i][j]
        maxSum = max(sum, maxSum)
    
    # Sum of operations across all rows
    for i in range(n):
        sum = 0
        for j in range(n):
            sum += mat[i][j]
        res += (maxSum - sum)
    
    return res


if __name__ == "__main__":
    mat = [
      [1, 2, 3], 
      [4, 2, 3], 
      [3, 2, 1]
    ]
    print(balanceSum(mat))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int balanceSum(int[][] mat) {
        int n = mat.Length;
        int res = 0;
        int maxSum = 0;

        // Find maximum sum across all rows
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = 0; j < n; j++)
                sum += mat[i][j];
            maxSum = Math.Max(sum, maxSum);
        }

        // Find maximum sum across all columns
        for (int j = 0; j < n; j++) {
            int sum = 0;
            for (int i = 0; i < n; i++)
                sum += mat[i][j];
            maxSum = Math.Max(sum, maxSum);
        }

        // Sum of operations across all rows
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = 0; j < n; j++)
                sum += mat[i][j];
            res += (maxSum - sum);
        }
        return res;
    }

    static void Main(string[] args) {
        int[][] mat = {
            new int[] { 1, 2, 3 },
            new int[] { 4, 2, 3 },
            new int[] { 3, 2, 1 }
        };
        Console.WriteLine(balanceSum(mat));
    }
}
JavaScript
function balanceSum(mat) {
    let n = mat.length;
    let res = 0;
    let maxSum = 0;

    // Find maximum sum across all rows
    for (let i = 0; i < n; i++) {
        let sum = 0;
        for (let j = 0; j < n; j++) {
            sum += mat[i][j];
        }
        maxSum = Math.max(sum, maxSum);
    }

    // Find maximum sum across all columns
    for (let j = 0; j < n; j++) {
        let sum = 0;
        for (let i = 0; i < n; i++) {
            sum += mat[i][j];
        }
        maxSum = Math.max(sum, maxSum);
    }

    // Sum of operations across all rows
    for (let i = 0; i < n; i++) {
        let sum = 0;
        for (let j = 0; j < n; j++) {
            sum += mat[i][j];
        }
        res += (maxSum - sum);
    }
    return res;
}

// Driver Code
let mat = [
    [ 1, 2, 3 ], 
    [ 4, 2, 3 ], 
    [ 3, 2, 1 ]
];
console.log(balanceSum(mat));

Output
6

Minimum Operations Required to Make Each Row and Column of Matrix Equals
Visit Course explore course icon
Article Tags :
Practice Tags :

Similar Reads