Given two N X M matrices of integers. In an operation, we can transpose any square sub-matrix in matrix1. The task is to check if matrix1 can be converted to matrix2 with the given operation.
Examples:
Input: matrix1[][] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}},
matrix2[][] = {
{1, 4, 7},
{2, 5, 6},
{3, 8, 9}}
Output: Yes
Transpose the whole matrix and then we transpose the
sub-matrix with corners in cells (2, 2) and (3, 3).
Input: matrix1[][] = {
{1, 2},
{3, 4}},
matrix2[][] = {
{1, 4},
{3, 8}}
Output: No
Approach: Sort the diagonals of both the matrices and compare them. If both matrices are equal after sorting diagonals, then matrix1 can be converted to matrix2. The following method is correct because of the fact that while transposing the numbers can only be transposed to any of its diagonal.
Below is the implementation of the above approach.
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
#define n 3 #define m 3 // Function that returns true if matrix1 // can be converted to matrix2 // with the given operation bool check( int a[n][m], int b[n][m])
{ // Traverse all the diagonals
// starting at first column
for ( int i = 0; i < n; i++) {
vector< int > v1, v2;
int r = i;
int col = 0;
// Traverse in diagonal
while (r >= 0 && col < m) {
// Store the diagonal elements
v1.push_back(a[r][col]);
v2.push_back(b[r][col]);
// Move up
r--;
col++;
}
// Sort the elements
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
// Check if they are same
for ( int i = 0; i < v1.size(); i++) {
if (v1[i] != v2[i])
return false ;
}
}
// Traverse all the diagonals
// starting at last row
for ( int j = 1; j < m; j++) {
vector< int > v1, v2;
int r = n - 1;
int col = j;
// Traverse in the diagonal
while (r >= 0 && col < m) {
// Store diagonal elements
v1.push_back(a[r][col]);
v2.push_back(b[r][col]);
r--;
col++;
}
// Sort all elements
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
// Check for same
for ( int i = 0; i < v1.size(); i++) {
if (v1[i] != v2[i])
return false ;
}
}
// If every element matches
return true ;
} // Driver code int main()
{ int a[n][m] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int b[n][m] = { { 1, 4, 7 }, { 2, 5, 6 }, { 3, 8, 9 } };
if (check(a, b))
cout << "Yes" ;
else
cout << "No" ;
return 0;
} |
// Java implementation of the approach import java.util.*;
class GFG
{ static final int n = 3 ;
static final int m = 3 ;
// Function that returns true if matrix1
// can be converted to matrix2
// with the given operation
static boolean check( int a[][], int b[][])
{
// Traverse all the diagonals
// starting at first column
for ( int i = 0 ; i < n; i++)
{
Vector<Integer> v1 = new Vector<Integer>();
Vector<Integer> v2 = new Vector<Integer>();
int r = i;
int col = 0 ;
// Traverse in diagonal
while (r >= 0 && col < m)
{
// Store the diagonal elements
v1.add(a[r][col]);
v2.add(b[r][col]);
// Move up
r--;
col++;
}
// Sort the elements
Collections.sort(v1);
Collections.sort(v2);
// Check if they are same
for ( int j = 0 ; j < v1.size(); j++)
{
if (v1.get(j) != v2.get(j))
{
return false ;
}
}
}
// Traverse all the diagonals
// starting at last row
for ( int j = 1 ; j < m; j++)
{
Vector<Integer> v1 = new Vector<Integer>();
Vector<Integer> v2 = new Vector<Integer>();
int r = n - 1 ;
int col = j;
// Traverse in the diagonal
while (r >= 0 && col < m)
{
// Store diagonal elements
v1.add(a[r][col]);
v2.add(b[r][col]);
r--;
col++;
}
// Sort all elements
Collections.sort(v1);
Collections.sort(v2);
// Check for same
for ( int i = 0 ; i < v1.size(); i++)
{
if (v1.get(i) != v2.get(i))
{
return false ;
}
}
}
// If every element matches
return true ;
}
// Driver code
public static void main(String[] args)
{
int a[][] = {{ 1 , 2 , 3 }, { 4 , 5 , 6 }, { 7 , 8 , 9 }};
int b[][] = {{ 1 , 4 , 7 }, { 2 , 5 , 6 }, { 3 , 8 , 9 }};
if (check(a, b))
{
System.out.println( "Yes" );
}
else
{
System.out.println( "No" );
}
}
} // This code contributed by Rajput-Ji |
# Python 3 implementation of the approach n = 3
m = 3
# Function that returns true if matrix1 # can be converted to matrix2 # with the given operation def check(a, b):
# Traverse all the diagonals
# starting at first column
for i in range (n):
v1 = []
v2 = []
r = i
col = 0
# Traverse in diagonal
while (r > = 0 and col < m):
# Store the diagonal elements
v1.append(a[r][col])
v2.append(b[r][col])
# Move up
r - = 1
col + = 1
# Sort the elements
v1.sort(reverse = False )
v2.sort(reverse = False )
# Check if they are same
for i in range ( len (v1)):
if (v1[i] ! = v2[i]):
return False
# Traverse all the diagonals
# starting at last row
for j in range ( 1 , m):
v1 = []
v2 = []
r = n - 1
col = j
# Traverse in the diagonal
while (r > = 0 and col < m):
# Store diagonal elements
v1.append(a[r][col])
v2.append(b[r][col])
r - = 1
col + = 1
# Sort all elements
v1.sort(reverse = False )
v2.sort(reverse = False )
# Check for same
for i in range ( len (v1)):
if (v1[i] ! = v2[i]):
return False
# If every element matches
return True
# Driver code if __name__ = = '__main__' :
a = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]]
b = [[ 1 , 4 , 7 ], [ 2 , 5 , 6 ], [ 3 , 8 , 9 ]]
if (check(a, b)):
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by # Surendra_Gangwar |
// C# implementation of the approach using System;
using System.Collections.Generic;
class GFG
{ static readonly int n = 3;
static readonly int m = 3;
// Function that returns true if matrix1
// can be converted to matrix2
// with the given operation
static bool check( int [,]a, int [,]b)
{
// Traverse all the diagonals
// starting at first column
for ( int i = 0; i < n; i++)
{
List< int > v1 = new List< int >();
List< int > v2 = new List< int >();
int r = i;
int col = 0;
// Traverse in diagonal
while (r >= 0 && col < m)
{
// Store the diagonal elements
v1.Add(a[r, col]);
v2.Add(b[r, col]);
// Move up
r--;
col++;
}
// Sort the elements
v1.Sort();
v2.Sort();
// Check if they are same
for ( int j = 0; j < v1.Count; j++)
{
if (v1[j] != v2[j])
{
return false ;
}
}
}
// Traverse all the diagonals
// starting at last row
for ( int j = 1; j < m; j++)
{
List< int > v1 = new List< int >();
List< int > v2 = new List< int >();
int r = n - 1;
int col = j;
// Traverse in the diagonal
while (r >= 0 && col < m)
{
// Store diagonal elements
v1.Add(a[r, col]);
v2.Add(b[r, col]);
r--;
col++;
}
// Sort all elements
v1.Sort();
v2.Sort();
// Check for same
for ( int i = 0; i < v1.Count; i++)
{
if (v1[i] != v2[i])
{
return false ;
}
}
}
// If every element matches
return true ;
}
// Driver code
public static void Main()
{
int [,]a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int [,]b = {{1, 4, 7}, {2, 5, 6}, {3, 8, 9}};
if (check(a, b))
{
Console.WriteLine( "Yes" );
}
else
{
Console.WriteLine( "No" );
}
}
} /* This code contributed by PrinciRaj1992 */ |
<?php // PHP implementation of the approach $n = 3;
$m = 3;
// Function that returns true if matrix1 // can be converted to matrix2 // with the given operation function check( $a , $b )
{ global $n , $m ;
// Traverse all the diagonals
// starting at first column
for ( $i = 0; $i < $n ; $i ++)
{
$v1 = array ();
$v2 = array ();
$r = $i ;
$col = 0;
// Traverse in diagonal
while ( $r >= 0 && $col < $m )
{
// Store the diagonal elements
array_push ( $v1 , $a [ $r ][ $col ]);
array_push ( $v2 , $b [ $r ][ $col ]);
// Move up
$r --;
$col ++;
}
// Sort the elements
sort( $v1 );
sort( $v2 );
// Check if they are same
for ( $i = 0; $i < count ( $v1 ); $i ++)
{
if ( $v1 [ $i ] != $v2 [ $i ])
return false;
}
}
// Traverse all the diagonals
// starting at last row
for ( $j = 1; $j < $m ; $j ++)
{
$v1 = array ();
$v2 = array ();
$r = $n - 1;
$col = $j ;
// Traverse in the diagonal
while ( $r >= 0 && $col < $m )
{
// Store diagonal elements
array_push ( $v1 , $a [ $r ][ $col ]);
array_push ( $v2 , $b [ $r ][ $col ]);
$r --;
$col ++;
}
// Sort all elements
sort( $v1 );
sort( $v2 );
// Check for same
for ( $i = 0; $i < count ( $v1 ); $i ++)
{
if ( $v1 [ $i ] != $v2 [ $i ])
return false;
}
}
// If every element matches
return true;
} // Driver code $a = array ( array ( 1, 2, 3 ),
array ( 4, 5, 6 ),
array ( 7, 8, 9 ));
$b = array ( array ( 1, 4, 7 ),
array ( 2, 5, 6 ),
array ( 3, 8, 9 ));
if (check( $a , $b ))
echo "Yes" ;
else echo "No" ;
// This code is contributed by mits ?> |
<script> // JavaScript implementation of the approach var n = 3
var m = 3
// Function that returns true if matrix1 // can be converted to matrix2 // with the given operation function check(a, b)
{ // Traverse all the diagonals
// starting at first column
for ( var i = 0; i < n; i++) {
var v1 = [], v2 = [];
var r = i;
var col = 0;
// Traverse in diagonal
while (r >= 0 && col < m) {
// Store the diagonal elements
v1.push(a[r][col]);
v2.push(b[r][col]);
// Move up
r--;
col++;
}
// Sort the elements
v1.sort();
v2.sort();
// Check if they are same
for ( var i = 0; i < v1.length; i++) {
if (v1[i] != v2[i])
return false ;
}
}
// Traverse all the diagonals
// starting at last row
for ( var j = 1; j < m; j++) {
var v1 = [], v2 = [];
var r = n - 1;
var col = j;
// Traverse in the diagonal
while (r >= 0 && col < m) {
// Store diagonal elements
v1.push(a[r][col]);
v2.push(b[r][col]);
r--;
col++;
}
// Sort all elements
v1.sort();
v2.sort();
// Check for same
for ( var i = 0; i < v1.length; i++) {
if (v1[i] != v2[i])
return false ;
}
}
// If every element matches
return true ;
} // Driver code var a = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];
var b = [ [ 1, 4, 7 ], [ 2, 5, 6 ], [ 3, 8, 9 ] ];
if (check(a, b))
document.write( "Yes" );
else document.write( "No" );
</script> |
Yes
Time Complexity: O(max(N *M*logM, N*M * logN)) which can be written as O(N*M*max(logN,logM)), as we are using a loop to traverse N times and we are using sort function on an array of size M which will cost O(M*logM) and we are also traversing M times and sorting an array of size N which will cost O(N*logN).
Auxiliary Space: O(max(N,M)), as we are using extra space for the array v1 and v2.