Given two matrices mat1[][] and mat2[][] of size N*M, the task is check if it is possible to transform mat1 into mat2 by selecting any square sub-matrix from mat1 and flipping it along its principal diagonal or anti-diagonal.
 Are Equal
Examples:
Input: N = 2, M = 3, mat1[][] = {{1, 2, 3}, {4, 5, 6}}, mat2[][] = {{1, 4, 3}, {6, 5, 2}} Output: YES Explanation:
 Are Equal
Input: N = 3, M = 3, mat1[][] = {{12, 11, 8}, {7, 1, 1}, {9, 2, 4}}, mat2[][] = {{4, 1, 8}, {2, 1, 11}, {9, 7, 15}} Output: NO Explanation: It can be verified that it is not possible to make all mat1[][] equal to mat2[][].
Approach:
The problem is observation based. If we assume the matrix as a chessboard and then map the color (Black & White) with elements. Then it is possible to place the element having black cell at any cell of whole matrix which have black cell using given operation. Same with the white cell elements. So, according to this observation, conversion from matrix mat1 to mat2 will be possible only and only if, the same element present at same colored cell in both matrices. Therefore, we will follow the below approach to solve the problem:
- Create 4 HashSets having name as B1, W1, B2, W2. Where:
- B1 will store the elements placed at black cells in matrix mat1[][].
- W1 will store the elements placed at white cells in matrix mat1[][].
- B2 will store the elements placed at black cells in matrix mat2[][].
- W2 will store the elements placed at white cells in matrix mat2[][].
After that conversion from mat1 to mat2 will be possible only and only if (B1 == B2 && W1 == W2).
For implementing the approach, the element at position (i, j) such that ((i + j) % 2 == 0) is assumed to place on Black cell for all (1 <= i <= N) and (1 <= j <= M).
Steps-by-step approach:
- If there is only 1 row or 1 column in mat1[][] and mat2[][]. Then check manually for equality of elements and output YES/NO by same.
- Otherwise,
- Create 4 HashSets as B1, B2, W1, W2.
- Run two nested loops from i= 0 to i < N and j = 0 to j < M and follow below mentioned steps under the scope of inner loop:
- If ((i+j) % 2 == 0)
- B1.add(A[i][j])
- B2.add(B[i][j])
- Else
- W1.add(A[i][j])
- W2.add(B[i][j])
- If (B1 contains same elements as B2 and W1 contains same elements as W2)
- Otherwise
Below is the implementation of the above approach:
C++
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
void Check_Possibility( int N, int M, vector<vector< long long >>& mat1,
vector<vector< long long >>& mat2);
int main()
{
int N = 2;
int M = 3;
vector<vector< long long >> mat1 = { { 1, 2, 3 }, { 4, 5, 6 } };
vector<vector< long long >> mat2 = { { 1, 4, 3 }, { 6, 5, 2 } };
Check_Possibility(N, M, mat1, mat2);
return 0;
}
void Check_Possibility( int N, int M, vector<vector< long long >>& mat1,
vector<vector< long long >>& mat2)
{
if (N == 1 || M == 1) {
bool flag = true ;
if (N == 1) {
for ( int i = 0; i < M; i++) {
if (mat1[0][i] != mat2[0][i]) {
flag = false ;
break ;
}
}
}
else {
for ( int i = 0; i < N; i++) {
if (mat1[i][0] != mat2[i][0]) {
flag = false ;
break ;
}
}
}
cout << (flag ? "YES" : "NO" ) << endl;
return ;
}
unordered_set< long long > black1, black2, white1, white2;
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
if ((i + j) % 2 == 0) {
black1.insert(mat1[i][j]);
black2.insert(mat2[i][j]);
} else {
white1.insert(mat1[i][j]);
white2.insert(mat2[i][j]);
}
}
}
if (black1 == black2 && white1 == white2) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
|
Java
import java.util.*;
public class Main {
public static void main(String[] args)
{
int N = 2 ;
int M = 3 ;
long [][] mat1 = { { 1 , 2 , 3 }, { 4 , 5 , 6 } };
long [][] mat2 = { { 1 , 4 , 3 }, { 6 , 5 , 2 } };
Check_Possibility(N, M, mat1, mat2);
}
public static void Check_Possibility( int N, int M,
long [][] mat1,
long [][] mat2)
{
if (N == 1 || M == 1 ) {
boolean flag = true ;
if (N == 1 ) {
for ( int i = 0 ; i < M; i++) {
if (mat1[ 0 ][i] != mat2[ 0 ][i]) {
flag = false ;
break ;
}
}
}
else {
for ( int i = 0 ; i < N; i++) {
if (mat1[i][ 0 ] != mat2[i][ 0 ]) {
flag = false ;
break ;
}
}
}
System.out.println(flag ? "YES" : "NO" );
return ;
}
HashSet<Long> black1 = new HashSet<>();
HashSet<Long> black2 = new HashSet<>();
HashSet<Long> white1 = new HashSet<>();
HashSet<Long> white2 = new HashSet<>();
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
if ((i + j) % 2 == 0 ) {
black1.add(mat1[i][j]);
black2.add(mat2[i][j]);
}
else {
white1.add(mat1[i][j]);
white2.add(mat2[i][j]);
}
}
}
if (black1.equals(black2)
&& white1.equals(white2)) {
System.out.println( "YES" );
}
else {
System.out.println( "NO" );
}
}
}
|
C#
using System;
using System.Collections.Generic;
class Program
{
static void CheckPossibility( int N, int M, List<List< long >> mat1, List<List< long >> mat2)
{
if (N == 1 || M == 1)
{
bool flag = true ;
if (N == 1)
{
for ( int i = 0; i < M; i++)
{
if (mat1[0][i] != mat2[0][i])
{
flag = false ;
break ;
}
}
}
else
{
for ( int i = 0; i < N; i++)
{
if (mat1[i][0] != mat2[i][0])
{
flag = false ;
break ;
}
}
}
Console.WriteLine(flag ? "YES" : "NO" );
return ;
}
HashSet< long > black1 = new HashSet< long >();
HashSet< long > black2 = new HashSet< long >();
HashSet< long > white1 = new HashSet< long >();
HashSet< long > white2 = new HashSet< long >();
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < M; j++)
{
if ((i + j) % 2 == 0)
{
black1.Add(mat1[i][j]);
black2.Add(mat2[i][j]);
}
else
{
white1.Add(mat1[i][j]);
white2.Add(mat2[i][j]);
}
}
}
if (black1.SetEquals(black2) && white1.SetEquals(white2))
{
Console.WriteLine( "YES" );
}
else
{
Console.WriteLine( "NO" );
}
}
static void Main()
{
int N = 2;
int M = 3;
List<List< long >> mat1 = new List<List< long >> { new List< long > { 1, 2, 3 }, new List< long > { 4, 5, 6 } };
List<List< long >> mat2 = new List<List< long >> { new List< long > { 1, 4, 3 }, new List< long > { 6, 5, 2 } };
CheckPossibility(N, M, mat1, mat2);
}
}
|
Javascript
function checkPossibility(N, M, mat1, mat2) {
if (N === 1 || M === 1) {
let flag = true ;
if (N === 1) {
for (let i = 0; i < M; i++) {
if (mat1[0][i] !== mat2[0][i]) {
flag = false ;
break ;
}
}
}
else {
for (let i = 0; i < N; i++) {
if (mat1[i][0] !== mat2[i][0]) {
flag = false ;
break ;
}
}
}
console.log(flag ? "YES" : "NO" );
return ;
}
let black1 = new Set(),
black2 = new Set(),
white1 = new Set(),
white2 = new Set();
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if ((i + j) % 2 === 0) {
black1.add(mat1[i][j]);
black2.add(mat2[i][j]);
} else {
white1.add(mat1[i][j]);
white2.add(mat2[i][j]);
}
}
}
if (setEquals(black1, black2) && setEquals(white1, white2)) {
console.log( "YES" );
} else {
console.log( "NO" );
}
}
function setEquals(set1, set2) {
if (set1.size !== set2.size) return false ;
for (let item of set1) {
if (!set2.has(item)) return false ;
}
return true ;
}
let N = 2;
let M = 3;
let mat1 = [[1, 2, 3], [4, 5, 6]];
let mat2 = [[1, 4, 3], [6, 5, 2]];
checkPossibility(N, M, mat1, mat2);
|
Python3
def check_possibility(N, M, mat1, mat2):
if N = = 1 or M = = 1 :
flag = True
if N = = 1 :
for i in range (M):
if mat1[ 0 ][i] ! = mat2[ 0 ][i]:
flag = False
break
else :
for i in range (N):
if mat1[i][ 0 ] ! = mat2[i][ 0 ]:
flag = False
break
print ( "YES" if flag else "NO" )
return
black1, black2, white1, white2 = set (), set (), set (), set ()
for i in range (N):
for j in range (M):
if (i + j) % 2 = = 0 :
black1.add(mat1[i][j])
black2.add(mat2[i][j])
else :
white1.add(mat1[i][j])
white2.add(mat2[i][j])
if black1 = = black2 and white1 = = white2:
print ( "YES" )
else :
print ( "NO" )
if __name__ = = "__main__" :
N = 2
M = 3
mat1 = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ]]
mat2 = [[ 1 , 4 , 3 ], [ 6 , 5 , 2 ]]
check_possibility(N, M, mat1, mat2)
|
Time Complexity: O(M*N) Auxiliary Space: O(N), As multiple HashSets are used.
|