Open In App

Queries to find index of Kth occurrence of X in diagonal traversal of a Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

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++14




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




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


Python3




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




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




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


Output: 

3
4
-1

 

Time Complexity: O(N*M+Q)
Auxiliary Space: O(N*M)



Last Updated : 16 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads