给定一个大小为N*M的矩阵A[][]和一个由{X, K}形式的查询组成的二维数组Q[][] ,每个查询的任务是找到第K个出现的位置从左到右对角线遍历时矩阵中的元素X。如果矩阵中元素X的频率小于K ,则打印“-1” 。
例子:
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
朴素方法:解决给定问题的最简单方法是对每个查询对角遍历矩阵,并找到元素Q[i][0] 的第Q[i][1]次出现。如果第Q[i][1]次出现不存在,则打印“-1” 。否则,打印该事件。
时间复杂度: O(Q*N*M)
辅助空间: O(1)
高效方法:为了优化上述方法,其思想是将给定矩阵的对角遍历的每个元素的索引存储在一个HashMap中,然后针对每个查询找到相应的索引。请按照以下步骤解决问题:
- 初始化一个 HashMap M来存储每个元素在矩阵对角线遍历中的位置。
- 对角遍历矩阵,并将遍历中每个元素的索引存储在 HashMap M 中。
- 现在,遍历查询Q[][]并对每个查询{X, K}执行以下步骤:
- 如果X不存在于M 或者X的出现小于K ,打印“-1” 。
- 否则,打印 HashMap M中元素X第K次出现的位置。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
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 > arr,
vector > 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 > 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 > A = { { 1, 4 },
{ 2, 5 } };
vector > 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> arr,
Vector> 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> um = new HashMap>();
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());
}
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());
}
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());
}
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());
}
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> A = new Vector>();
A.add(new Vector());
A.get(0).add(1);
A.get(0).add(4);
A.add(new Vector());
A.get(1).add(2);
A.get(1).add(5);
Vector> Q = new Vector>();
Q.add(new Vector());
Q.get(0).add(4);
Q.get(0).add(1);
Q.add(new Vector());
Q.get(1).add(5);
Q.get(1).add(1);
Q.add(new Vector());
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> arr, List> 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> um = new Dictionary>();
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();
}
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();
}
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();
}
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();
}
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> A = new List>();
A.Add(new List());
A[0].Add(1);
A[0].Add(4);
A.Add(new List());
A[1].Add(2);
A[1].Add(5);
List> Q = new List>();
Q.Add(new List());
Q[0].Add(4);
Q[0].Add(1);
Q.Add(new List());
Q[1].Add(5);
Q[1].Add(1);
Q.Add(new List());
Q[2].Add(10);
Q[2].Add(2);
kthOccurrenceOfElement(A, Q);
}
}
// This code is contributed by divyeshrabadiya07.
3
4
-1
时间复杂度: O(N*M+Q)
辅助空间: O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。