Open In App

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

Last Updated : 03 May, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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:

C++




// 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);
}


Java




// 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


Python3




# 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


C#




// 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


Javascript




<script>
 
// Javascript program to implement
// the above approach
 
    // Function to count the minimum
    // number of adjacent swaps
    function minAdjSwaps(mat) {
 
        // Stores the size of
        // the given matrix
        var N = mat.length;
 
        // Stores the count of zero
        // at the end of each row
        var cntZero = Array(N).fill(0);
 
        // Traverse the given matrix
        for (i = 0; i < N; i++) {
 
            // Count of 0s at the end
            // of the ith row
            for (j = N - 1; j >= 0 &&
            mat[i][j] == 0; j--)
            {
                cntZero[i]++;
            }
        }
 
        // Stores the count of swaps
        var cntSwaps = 0;
 
        // Traverse the cntZero array
        for (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)
                var 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;
    }
 
    function swap(arr , i , j) {
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }
 
    // Driver Code
     
        var mat = [ [ 0, 0, 2 ],
        [ 3, 1, 0 ],
        [ 4, 0, 0 ] ];
 
        document.write(minAdjSwaps(mat));
 
// This code contributed by gauravrajput1
 
</script>


Output

3

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads