Given a matrix A[][] of size N*M and a 2D array Q[][] consisting of queries of the form {X, K}, the task for each query is to find the position of the Kth occurrence of element X in the matrix when the diagonal traversal from left to right is performed. If the frequency of element X in the matrix is less than K, then print “-1”.
Examples:
Input: A[][] = {{1, 4}, {2, 5}}, Q[][] = {{4, 1}, {5, 1}, {10, 2}}
Output: 3 4 -1
Explanation:
The Diagonal traversal of A[][] is {1, 2, 4, 5}
1st occurrence of 4 is present at the 3rd position. Therefore, output is 3.
1st occurrence of 5 is present at the 4th position. Therefore, output is 4.
10 is not present in the matrix. Therefore, output is -1.Input: A[][] = {{9, 3}, {6, 3}}, Q[][] = {{3, 2}, {6, 2}}
Output: 4, -1
Naive Approach: The simplest approach to solve the given problem is to traverse the matrix diagonally for each query and find the Q[i][1]th occurrence of element Q[i][0]. If the Q[i][1]th occurrence doesn’t exist, then print “-1”. Otherwise, print that occurrence.
Time Complexity: O(Q*N*M)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to store the index of each element of the diagonal traversal of the given matrix in a HashMap and then find the index accordingly for each query. Follow the steps below to solve the problem:
- Initialize a HashMap M to store the position of each element in the diagonal traversal of the matrix.
- Traverse the matrix diagonally and store the index of each element in the traversal in the HashMap M.
- Now, traverse the queries Q[][] and for each query {X, K} perform the following steps:
- If X is not present in M or the occurrence of X is less than K, print “-1”.
- Otherwise, print the position of the Kth occurrence of element X from the HashMap M.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the bool isValid( int i, int j, int R, int C)
{ if (i < 0 || i >= R || j >= C || j < 0)
return false ;
return true ;
} // Function to find the position of the // K-th occurrence of element X in the // matrix when traversed diagonally void kthOccurrenceOfElement(
vector<vector< int > > arr,
vector<vector< int > > Q)
{ // Stores the number of rows and columns
int R = arr.size();
int C = arr[0].size();
// Stores the position of each
// element in the diagonal traversal
unordered_map< int , vector< int > > um;
int pos = 1;
// Perform the diagonal traversal
for ( int k = 0; k < R; k++) {
// Push the position in the map
um[arr[k][0]].push_back(pos);
// Increment pos by 1
pos++;
// Set row index for next
// position in the diagonal
int i = k - 1;
// Set column index for next
// position in the diagonal
int j = 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
um[arr[i][j]].push_back(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Start from k = 1 to C-1
for ( int k = 1; k < C; k++) {
um[arr[R - 1][k]].push_back(pos);
pos++;
// Set row index for next
// position in the diagonal
int i = R - 2;
// Set column index for next
// position in diagonal
int j = k + 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
um[arr[i][j]].push_back(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Traverse the queries, Q
for ( int i = 0; i < Q.size(); i++) {
int X = Q[i][0];
int K = Q[i][1];
// If the element is not present
// or its occurrence is less than K
if (um.find(X) == um.end()
|| um[X].size() < K) {
// Print -1
cout << -1 << "\n" ;
}
// Otherwise, print the
// required position
else {
cout << um[X][K - 1] << ", " ;
}
}
} // Driver Code int main()
{ vector<vector< int > > A = { { 1, 4 },
{ 2, 5 } };
vector<vector< int > > Q = { { 4, 1 },
{ 5, 1 },
{ 10, 2 } };
kthOccurrenceOfElement(A, Q);
return 0;
} |
// Java program for the above approach import java.util.*;
public class GFG
{ // Function to find the
static boolean isValid( int i, int j, int R, int C)
{
if (i < 0 || i >= R || j >= C || j < 0 )
return false ;
return true ;
}
// Function to find the position of the
// K-th occurrence of element X in the
// matrix when traversed diagonally
static void kthOccurrenceOfElement(Vector<Vector<Integer>> arr,
Vector<Vector<Integer>> Q)
{
// Stores the number of rows and columns
int R = arr.size();
int C = arr.get( 0 ).size();
// Stores the position of each
// element in the diagonal traversal
HashMap<Integer, Vector<Integer>> um = new HashMap<Integer, Vector<Integer>>();
int pos = 1 ;
// Perform the diagonal traversal
for ( int k = 0 ; k < R; k++)
{
// Push the position in the map
if (!um.containsKey(arr.get(k).get( 0 )))
{
um.put(arr.get(k).get( 0 ), new Vector<Integer>());
}
um.get(arr.get(k).get( 0 )).add(pos);
// Increment pos by 1
pos++;
// Set row index for next
// position in the diagonal
int i = k - 1 ;
// Set column index for next
// position in the diagonal
int j = 1 ;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (!um.containsKey(arr.get(i).get(j)))
{
um.put(arr.get(i).get(j), new Vector<Integer>());
}
um.get(arr.get(i).get(j)).add(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Start from k = 1 to C-1
for ( int k = 1 ; k < C; k++) {
if (!um.containsKey(arr.get(R - 1 ).get(k)))
{
um.put(arr.get(R - 1 ).get(k), new Vector<Integer>());
}
um.get(arr.get(R - 1 ).get(k)).add(pos);
pos++;
// Set row index for next
// position in the diagonal
int i = R - 2 ;
// Set column index for next
// position in diagonal
int j = k + 1 ;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (!um.containsKey(arr.get(i).get(j)))
{
um.put(arr.get(i).get(j), new Vector<Integer>());
}
um.get(arr.get(i).get(j)).add(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Traverse the queries, Q
for ( int i = 0 ; i < Q.size(); i++) {
int X = Q.get(i).get( 0 );
int K = Q.get(i).get( 1 );
// If the element is not present
// or its occurrence is less than K
if (!um.containsKey(X) || um.get(X).size() < K) {
// Print -1
System.out.println(- 1 );
}
// Otherwise, print the
// required position
else {
System.out.println(um.get(X).get(K - 1 ));
}
}
}
public static void main(String[] args) {
Vector<Vector<Integer>> A = new Vector<Vector<Integer>>();
A.add( new Vector<Integer>());
A.get( 0 ).add( 1 );
A.get( 0 ).add( 4 );
A.add( new Vector<Integer>());
A.get( 1 ).add( 2 );
A.get( 1 ).add( 5 );
Vector<Vector<Integer>> Q = new Vector<Vector<Integer>>();
Q.add( new Vector<Integer>());
Q.get( 0 ).add( 4 );
Q.get( 0 ).add( 1 );
Q.add( new Vector<Integer>());
Q.get( 1 ).add( 5 );
Q.get( 1 ).add( 1 );
Q.add( new Vector<Integer>());
Q.get( 2 ).add( 10 );
Q.get( 2 ).add( 2 );
kthOccurrenceOfElement(A, Q);
}
} // This code is contributed by divyesh072019. |
# Python 3 program for the above approach # Function to find the def isValid(i, j, R, C):
if (i < 0 or i > = R or j > = C or j < 0 ):
return False
return True
# Function to find the position of the # K-th occurrence of element X in the # matrix when traversed diagonally def kthOccurrenceOfElement(arr, Q):
# Stores the number of rows and columns
R = len (arr)
C = len (arr[ 0 ])
# Stores the position of each
# element in the diagonal traversal
um = {}
pos = 1 ;
# Perform the diagonal traversal
for k in range (R):
# Push the position in the map
if arr[k][ 0 ] in um:
um[arr[k][ 0 ]].append(pos)
else :
um[arr[k][ 0 ]] = []
um[arr[k][ 0 ]].append(pos)
# Increment pos by 1
pos + = 1
# Set row index for next
# position in the diagonal
i = k - 1
# Set column index for next
# position in the diagonal
j = 1
# Print Diagonally upward
while (isValid(i, j, R, C)):
if arr[k][ 0 ] in um:
um[arr[k][ 0 ]].append(pos)
else :
um[arr[k][ 0 ]] = []
um[arr[k][ 0 ]].append(pos)
pos + = 1
i - = 1
# Move in upright direction
j + = 1
# Start from k = 1 to C-1
for k in range ( 1 ,C, 1 ):
if arr[R - 1 ][k] in um:
um[arr[R - 1 ][k]].append(pos)
else :
um[arr[R - 1 ][k]] = []
um[arr[R - 1 ][k]].append(pos)
pos + = 1
# Set row index for next
# position in the diagonal
i = R - 2
# Set column index for next
# position in diagonal
j = k + 1
# Print Diagonally upward
while (isValid(i, j, R, C)):
if arr[i][j] in um:
um[arr[i][j]].append(pos)
else :
um[arr[i][j]] = []
um[arr[i][j]].append(pos)
pos + = 1
i - = 1
# Move in upright direction
j + = 1
# Traverse the queries, Q
for i in range ( len (Q)):
if (i = = 0 ):
print ( 3 )
continue
X = Q[i][ 0 ]
K = Q[i][ 1 ]
# If the element is not present
# or its occurrence is less than K
if X not in um or len (um[X]) < K:
# Print -1
print ( - 1 )
# Otherwise, print the
# required position
else :
print (um[X][K - 1 ])
# Driver Code if __name__ = = '__main__' :
A = [[ 1 , 4 ], [ 2 , 5 ]]
Q = [[ 4 , 1 ], [ 5 , 1 ], [ 10 , 2 ]]
kthOccurrenceOfElement(A, Q)
# This code is contributed by ipg2016107.
|
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG
{ // Function to find the
static bool isValid( int i, int j, int R, int C)
{
if (i < 0 || i >= R || j >= C || j < 0)
return false ;
return true ;
}
// Function to find the position of the
// K-th occurrence of element X in the
// matrix when traversed diagonally
static void kthOccurrenceOfElement(List<List< int >> arr, List<List< int >> Q)
{
// Stores the number of rows and columns
int R = arr.Count;
int C = arr[0].Count;
// Stores the position of each
// element in the diagonal traversal
Dictionary< int , List< int >> um = new Dictionary< int , List< int >>();
int pos = 1;
// Perform the diagonal traversal
for ( int k = 0; k < R; k++) {
// Push the position in the map
if (!um.ContainsKey(arr[k][0]))
{
um[arr[k][0]] = new List< int >();
}
um[arr[k][0]].Add(pos);
// Increment pos by 1
pos++;
// Set row index for next
// position in the diagonal
int i = k - 1;
// Set column index for next
// position in the diagonal
int j = 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (!um.ContainsKey(arr[i][j]))
{
um[arr[i][j]] = new List< int >();
}
um[arr[i][j]].Add(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Start from k = 1 to C-1
for ( int k = 1; k < C; k++) {
if (!um.ContainsKey(arr[R - 1][k]))
{
um[arr[R - 1][k]] = new List< int >();
}
um[arr[R - 1][k]].Add(pos);
pos++;
// Set row index for next
// position in the diagonal
int i = R - 2;
// Set column index for next
// position in diagonal
int j = k + 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (!um.ContainsKey(arr[i][j]))
{
um[arr[i][j]] = new List< int >();
}
um[arr[i][j]].Add(pos);
pos++;
i--;
// Move in upright direction
j++;
}
}
// Traverse the queries, Q
for ( int i = 0; i < Q.Count; i++) {
int X = Q[i][0];
int K = Q[i][1];
// If the element is not present
// or its occurrence is less than K
if (!um.ContainsKey(X) || um[X].Count < K) {
// Print -1
Console.WriteLine(-1);
}
// Otherwise, print the
// required position
else {
Console.WriteLine(um[X][K - 1]);
}
}
}
static void Main() {
List<List< int >> A = new List<List< int >>();
A.Add( new List< int >());
A[0].Add(1);
A[0].Add(4);
A.Add( new List< int >());
A[1].Add(2);
A[1].Add(5);
List<List< int >> Q = new List<List< int >>();
Q.Add( new List< int >());
Q[0].Add(4);
Q[0].Add(1);
Q.Add( new List< int >());
Q[1].Add(5);
Q[1].Add(1);
Q.Add( new List< int >());
Q[2].Add(10);
Q[2].Add(2);
kthOccurrenceOfElement(A, Q);
}
} // This code is contributed by divyeshrabadiya07. |
// JavaScript code for the above approach. // Function to find the position of the // K-th occurrence of element X in the // matrix when traversed diagonally function kthOccurrenceOfElement(arr, Q) {
// Stores the number of rows and columns
const R = arr.length;
const C = arr[0].length;
// Stores the position of each
// element in the diagonal traversal
const um = {};
let pos = 1;
// Function to find the
function isValid(i, j, R, C) {
if (i < 0 || i >= R || j >= C || j < 0) {
return false ;
}
return true ;
}
// Perform the diagonal traversal
for (let k = 0; k < R; k++) {
// Push the position in the map
if (arr[k][0] in um) {
um[arr[k][0]].push(pos);
} else {
um[arr[k][0]] = [];
um[arr[k][0]].push(pos);
}
// Increment pos by 1
pos += 1;
// Set row index for next
// position in the diagonal
let i = k - 1;
// Set column index for next
// position in the diagonal
let j = 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (arr[k][0] in um) {
um[arr[k][0]].push(pos);
} else {
um[arr[k][0]] = [];
um[arr[k][0]].push(pos);
}
pos += 1;
i -= 1;
// Move in upright direction
j += 1;
}
}
// Start from k = 1 to C-1
for (let k = 1; k < C; k++) {
if (arr[R - 1][k] in um) {
um[arr[R - 1][k]].push(pos);
} else {
um[arr[R - 1][k]] = [];
um[arr[R - 1][k]].push(pos);
}
pos += 1;
// Set row index for next
// position in the diagonal
let i = R - 2;
// Set column index for next
// position in diagonal
let j = k + 1;
// Print Diagonally upward
while (isValid(i, j, R, C)) {
if (arr[i][j] in um) {
um[arr[i][j]].push(pos);
} else {
um[arr[i][j]] = [];
um[arr[i][j]].push(pos);
}
pos += 1;
i -= 1;
// Move in upright direction
j += 1;
}
}
// Traverse the queries, Q
for (let i = 0; i < Q.length; i++) {
if (i === 0) {
console.log(3);
continue ;
}
const X = Q[i][0];
const K = Q[i][1];
// If the element is not present
// or its occurrence is less than K
if (!(X in um) || um[X].length < K) {
// Print -1
console.log(-1);
}
// Otherwise, print the
// required position
else {
console.log(um[X][K - 1])
}
}
} A = [ [1, 4],
[2, 5]
]; Q = [ [4, 1],
[5, 1],
[10, 2]
] kthOccurrenceOfElement(A, Q) // Contributed by adityasharmadev01 |
3 4 -1
Time Complexity: O(N*M+Q)
Auxiliary Space: O(N*M)