Minimize count of adjacent row swaps to convert given Matrix to a Lower Triangular Matrix

Given a matrix, mat[][] of size N × N, the task is to minimize the count of adjacent row swaps to convert the given matrix to a lower triangular matrix. If it is not possible to convert the given matrix to a lower triangular matrix, then print -1. 
Note: A lower triangular matrix contains 0s at all the indices above the main diagonal.

Examples:

Input: mat[][] = {{0, 0, 2}, {3, 1, 0}, {4, 0, 0}}
Output: 3
Explanation:  
Swap 1st row and 2nd row {{3, 1, 0}, {0, 0, 2}, {4, 0, 0}}
Swap 2nd row and 3rd row {{3, 1, 0}, {4, 0, 0}, {0, 0, 2}}
Swap 1st row and 2nd row {{4, 0, 0}, {3, 1, 0},  {0, 0, 2}}
Therefore, the required output is 3.

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

Approach: This problem can be solved using the Greedy technique. The idea to first find the count of zeros present in each row and store it in an integer array. Then, count the minimum number of adjacent swaps required to sort the array based on the number of 0s in descending order. Follow the steps below to solve the problem:

  1. Initialize an array, say cntZero[] to store the count of 0s present in each row.
  2. For ith row, traverse the cntZero[] array from (i + 1)th index and find the first index, say First where ctnZero[First] >= (N – i -1).
  3. Swap all the adjacent elements from the ith index to First index of cntZero[] array and increment the count.
  4. Finally, return the count of adjacent swaps required to convert the given matrix to the lower triangular matrix.

Below is the implementation of the above approach:



filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the minimum
// number of  adjacent swaps
int minAdjSwaps(vector<vector<int> >& mat)
{
    // Stores the size of
    // the given matrix
    int N = mat.size();
 
    // Stores the count of zero
    // at the end of each row
    vector<int> cntZero(N, 0);
 
    // Traverse the given matrix
    for (int i = 0; i < N; i++) {
 
        // Count of 0s at the end
        // of the ith row
        for (int j = N - 1;
             j >= 0 && mat[i][j] == 0;
             j--) {
            cntZero[i]++;
        }
    }
 
    // Stores the count of swaps
    int cntSwaps = 0;
 
    // Traverse the cntZero array
    for (int i = 0; i < N; i++) {
 
        // If count of zero in the
        // i-th row < (N - i - 1)
        if (cntZero[i]
            < (N - i - 1)) {
 
            // Stores the index of the row
            // where count of zero > (N-i-1)
            int First = i;
            while (First < N
                   && cntZero[First]
                          < (N - i - 1)) {
                First++;
            }
 
            // If no row found that
            // satisfy the condition
            if (First == N) {
                return -1;
            }
 
            // Swap the adjacent row
            while (First > i) {
                swap(cntZero[First],
                     cntZero[First - 1]);
                First--;
                cntSwaps++;
            }
        }
    }
    return cntSwaps;
}
 
// Driver Code
int main()
{
    vector<vector<int> > mat
        = { { 0, 0, 2 },
            { 3, 1, 0 },
            { 4, 0, 0 } };
    cout << minAdjSwaps(mat);
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to count the minimum
// number of  adjacent swaps
static int minAdjSwaps(int [][]mat)
{
     
    // Stores the size of
    // the given matrix
    int N = mat.length;
 
    // Stores the count of zero
    // at the end of each row
    int []cntZero = new int[N];
 
    // Traverse the given matrix
    for(int i = 0; i < N; i++)
    {
         
        // Count of 0s at the end
        // of the ith row
        for(int j = N - 1;
                j >= 0 && mat[i][j] == 0;
                j--)
        {
            cntZero[i]++;
        }
    }
 
    // Stores the count of swaps
    int cntSwaps = 0;
 
    // Traverse the cntZero array
    for(int i = 0; i < N; i++)
    {
         
        // If count of zero in the
        // i-th row < (N - i - 1)
        if (cntZero[i] < (N - i - 1))
        {
             
            // Stores the index of the row
            // where count of zero > (N-i-1)
            int First = i;
            while (First < N && cntZero[First] <
                  (N - i - 1))
            {
                First++;
            }
 
            // If no row found that
            // satisfy the condition
            if (First == N)
            {
                return -1;
            }
 
            // Swap the adjacent row
            while (First > i)
            {
                cntZero = swap(cntZero, First,
                               First - 1);
                First--;
                cntSwaps++;
            }
        }
    }
    return cntSwaps;
}
 
static int[] swap(int []arr, int i, int j)
{
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    return arr;
}
 
// Driver Code
public static void main(String[] args)
{
    int [][]mat = { { 0, 0, 2 },
                    { 3, 1, 0 },
                    { 4, 0, 0 } };
                     
    System.out.print(minAdjSwaps(mat));
}
}
 
// This code is contributed by Amit Katiyar
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
 
# Function to count the minimum
# number of  adjacent swaps
def minAdjSwaps(mat):
     
    # Stores the size of
    # the given matrix
    N = len(mat)
 
    # Stores the count of zero
    # at the end of each row
    cntZero = [0] * (N)
 
    # Traverse the given matrix
    for i in range(N):
 
        # Count of 0s at the end
        # of the ith row
        for j in range(N - 1, -1, -1):
            if mat[i][j] != 0:
                break
             
            cntZero[i] += 1
 
    # Stores the count of swaps
    cntSwaps = 0
 
    # Traverse the cntZero array
    for i in range(N):
 
        # If count of zero in the
        # i-th row < (N - i - 1)
        if (cntZero[i] < (N - i - 1)):
 
            # Stores the index of the row
            # where count of zero > (N-i-1)
            First = i
             
            while (First < N and
           cntZero[First] < (N - i - 1)):
                First += 1
 
            # If no row found that
            # satisfy the condition
            if (First == N):
                return -1
 
            # Swap the adjacent row
            while (First > i):
                cntZero[First] = cntZero[First - 1]
                cntZero[First - 1] = cntZero[First]
                 
                First -= 1
                cntSwaps += 1
                 
    return cntSwaps
 
# Driver Code
if __name__ == '__main__':
     
    mat = [ [ 0, 0, 2 ],
            [ 3, 1, 0 ],
            [ 4, 0, 0 ] ]
             
    print(minAdjSwaps(mat))
 
# This code is contributed by mohit kumar 29
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
class GFG{
 
// Function to count the minimum
// number of  adjacent swaps
static int minAdjSwaps(int [,]mat)
{
  // Stores the size of
  // the given matrix
  int N = mat.GetLength(0);
 
  // Stores the count of zero
  // at the end of each row
  int []cntZero = new int[N];
 
  // Traverse the given matrix
  for(int i = 0; i < N; i++)
  {
    // Count of 0s at the end
    // of the ith row
    for(int j = N - 1;
            j >= 0 && mat[i, j] == 0;
            j--)
    {
      cntZero[i]++;
    }
  }
 
  // Stores the count of swaps
  int cntSwaps = 0;
 
  // Traverse the cntZero array
  for(int i = 0; i < N; i++)
  {
    // If count of zero in the
    // i-th row < (N - i - 1)
    if (cntZero[i] < (N - i - 1))
    {
      // Stores the index of the row
      // where count of zero > (N-i-1)
      int First = i;
       
      while (First < N &&
             cntZero[First] < (N - i - 1))
      {
        First++;
      }
 
      // If no row found that
      // satisfy the condition
      if (First == N)
      {
        return -1;
      }
 
      // Swap the adjacent row
      while (First > i)
      {
        cntZero = swap(cntZero,
                       First, First - 1);
        First--;
        cntSwaps++;
      }
    }
  }
  return cntSwaps;
}
 
static int[] swap(int []arr,
                  int i, int j)
{
  int temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
  return arr;
}
 
// Driver Code
public static void Main(String[] args)
{
  int [,]mat = {{0, 0, 2},
                {3, 1, 0},
                {4, 0, 0}};
  Console.Write(minAdjSwaps(mat));
}
}
 
// This code is contributed by 29AjayKumar
chevron_right

Output
3

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

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.




Recommended Posts:


Still Learner

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 :