Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

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

  • Last Updated : 09 Aug, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 occurence 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 occurence 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 occurence 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 occurence 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.
Output: 
3
4
-1

 

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




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!