Minimum index at which 1 row and 1 column completely vanishes
Last Updated :
04 Oct, 2023
Given an array X[] and a matrix M[][]. Then the task is to output the minimum elements needed to remove so that one row and one column of M[][] becomes completely empty, return -1 if not possible. For that, you are allowed to remove the first element of X[] and remove the same element from M[][].
Note: All elements of X[] and M[][] are unique. All the elements of X[] will surely present in M[][], but vice – versa is not true.
Examples:
Input: X[] = {1, 4, 6, 2, 8, 7, 5, 9, 3}, M[][] = {{3, 2, 5}, {1, 4, 6}, {8, 7, 9}}
Output: 6
Explanation:
Input: X[] = {1, 4}, M[][] = {{3, 2}, {1, 4}}
Output: -1
Explanation: It can be verified that X[] becomes empty, But any row and any column of matrix didn’t become empty. Therefore, output is -1
Approach: Implement the idea below to solve the problem:
The problem can be solved by using HashMap for storing the position of element in M[][] and Frequency arrays for storing the frequency of vanished element of rows and columns. For more clarifications see the Concept of approach section below.
Concept of approach:
The problem can be solved easily, If we can get the location of an element in matrix efficiently and number of elements vanished in row and column. We can resolve both of this.
- How to get location of elements efficiently: Create a HashMap<Integer, Pair> which stores element and its location in Pair(Row, Col) in form of Key and Value. As it is given that all the elements are unique so no duplicacy will occur and map, Thus it is a perfect data structure to use here. After this we can get location of any element in O(1) time.
- How to get number of elements vanished in row or column: Create two frequency arrays Row[] and Col[], Which stores number of vanished elements in particular row or column. These frequency arrays will reduce time to check that any row or column is vanished or not.
After this just implement the below approach:
- Traverse on Matrix and initialize all elements’ location in map.
- Create two arrays Row[] and Col[].
- Traverse on X[] and get location of current element and increment number of vanished elements in row[] and col[] at same location.
- If any value in Row[] become equal to M[0].length and any value of column[] become equal to M.length.Then return the number of elements traversed in X[].
- Else return -1.
Steps were taken to solve the problem:
- Create a HashMap<Integer, Pair(int, int)> let’s say map for storing an element and its location.
- Run two nested loops for traversing on M[][] and initialize elements and their location in the map.
- Initialize a variable let’s say min_element for storing the minimum number of elements required.
- Create two frequency arrays Row[] and Col[] and two boolean variables Row_max and Col_max, and set them initially as false.
- Run a loop for traversing X[] and follow the below-mentioned steps under the scope of the loop:
- Increment min_element.
- Get the location of the current element of X[]. Let say location of current element in M[][] will be = (r, c)
- Increment Row[r] by 1.
- Increment Col by 1.
- If (Row[r] == M[0].length), Then mark Row_max flag as true.
- If (Col == M.length), then mark the Col_max flag as true.
- If (Row_max == True && Col_max == True), Then return the value of min_element.
- Return -1.
Below is the code to implement the approach:
C++
#include <iostream>
#include <unordered_map>
#include <utility>
using namespace std;
int Min_Element( int X[], int M[][2], int n, int m)
{
unordered_map< int , pair< int , int >> map;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
map[M[i][j]] = make_pair(i, j);
}
}
int row[n] = {0};
int col[m] = {0};
int min_element = 0;
bool row_max = false ;
bool col_max = false ;
for ( int i = 0; i < 2; i++) {
min_element++;
pair< int , int > y = map[X[i]];
row[y.first] += 1;
col[y.second] += 1;
if (row[y.first] == m) {
row_max = true ;
}
if (col[y.second] == n) {
col_max = true ;
}
if (row_max && col_max) {
return min_element;
}
}
return -1;
}
int main()
{
int X[] = { 1, 4 };
int M[][2] = {
{ 3, 2 },
{ 1, 4 },
};
int ans = Min_Element(X, M, 2, 2);
cout << ans << endl;
return 0;
}
|
Java
import java.util.*;
class pair {
int row, col;
pair( int row, int col)
{
this .row = row;
this .col = col;
}
}
public class GFG {
public static void main(String[] args)
{
int [] X = { 1 , 4 };
int [][] M = {
{ 3 , 2 },
{ 1 , 4 },
};
int ans = Min_Element(X, M);
System.out.println(ans);
}
static int Min_Element( int [] X, int [][] M)
{
HashMap<Integer, pair> map = new HashMap<>();
for ( int i = 0 ; i < M.length; i++) {
for ( int j = 0 ; j < M[ 0 ].length; j++) {
map.put(M[i][j], new pair(i, j));
}
}
int [] row = new int [M.length];
int [] col = new int [M[ 0 ].length];
int min_element = 0 ;
boolean row_max = false ;
boolean col_max = false ;
for ( int i = 0 ; i < X.length; i++) {
min_element++;
pair y = map.get(X[i]);
row[y.row] += 1 ;
col[y.col] += 1 ;
if (row[y.row] == M[ 0 ].length) {
row_max = true ;
}
if (col[y.col] == M.length) {
col_max = true ;
}
if (row_max && col_max) {
return min_element;
}
}
return - 1 ;
}
}
|
Python3
class Pair:
def __init__( self , row, col):
self .row = row
self .col = col
def min_element(X, M):
map = {}
for i in range ( len (M)):
for j in range ( len (M[ 0 ])):
map [M[i][j]] = Pair(i, j)
row = [ 0 ] * len (M)
col = [ 0 ] * len (M[ 0 ])
min_element = 0
row_max = False
col_max = False
for i in range ( len (X)):
min_element + = 1
y = map [X[i]]
row[y.row] + = 1
col[y.col] + = 1
if row[y.row] = = len (M[ 0 ]):
row_max = True
if col[y.col] = = len (M):
col_max = True
if row_max and col_max:
return min_element
return - 1
if __name__ = = "__main__" :
X = [ 1 , 4 ]
M = [
[ 3 , 2 ],
[ 1 , 4 ],
]
ans = min_element(X, M)
print (ans)
|
C#
using System;
using System.Collections.Generic;
public class Solution
{
private static int MinElement( int [] X, int [,] M, int n, int m)
{
Dictionary< int , Tuple< int , int >> map = new Dictionary< int , Tuple< int , int >>();
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < m; j++)
{
map[M[i, j]] = Tuple.Create(i, j);
}
}
int [] row = new int [n];
int [] col = new int [m];
int minElement = 0;
bool rowMax = false ;
bool colMax = false ;
for ( int i = 0; i < 2; i++)
{
minElement++;
Tuple< int , int > y = map[X[i]];
row[y.Item1] += 1;
col[y.Item2] += 1;
if (row[y.Item1] == m)
{
rowMax = true ;
}
if (col[y.Item2] == n)
{
colMax = true ;
}
if (rowMax && colMax)
{
return minElement;
}
}
return -1;
}
public static void Main( string [] args)
{
int [] X = { 1, 4 };
int [,] M = {
{ 3, 2 },
{ 1, 4 }
};
int ans = MinElement(X, M, 2, 2);
Console.WriteLine(ans);
}
}
|
Javascript
class Pair {
constructor(row, col) {
this .row = row;
this .col = col;
}
}
function minElement(X, M) {
const map = new Map();
for (let i = 0; i < M.length; i++) {
for (let j = 0; j < M[0].length; j++) {
map.set(M[i][j], new Pair(i, j));
}
}
const row = new Array(M.length).fill(0);
const col = new Array(M[0].length).fill(0);
let minElementCount = 0;
let rowMax = false ;
let colMax = false ;
for (let i = 0; i < X.length; i++) {
minElementCount++;
const y = map.get(X[i]);
row[y.row]++;
col[y.col]++;
if (row[y.row] === M[0].length) {
rowMax = true ;
}
if (col[y.col] === M.length) {
colMax = true ;
}
if (rowMax && colMax) {
return minElementCount;
}
}
return -1;
}
const X = [1, 4];
const M = [
[3, 2],
[1, 4]
];
const ans = minElement(X, M);
console.log(ans);
|
Time Complexity: O(M*N), As HashMap is used to store the location of an element in M[][] in the form of Pairs.
Auxiliary Space: O((M + N) + (M*N)), Frequency arrays of size M and N are used to store values. Where M and N are the numbers of rows and columns of M[][] and HashMap of space (N*M) is used.
Share your thoughts in the comments
Please Login to comment...