Dada una Grid de tamaño NxM y dos enteros X e Y , la tarea es contar el número mínimo de filas entre la fila que contiene X y la fila que contiene Y de tal manera que las filas adyacentes entre ellas tengan al menos un elemento en común. Se permiten varias apariciones de un número en la cuadrícula. En otras palabras, se dice que dos filas son adyacentes si tienen al menos un elemento en común.
Ejemplos:
Entrada: arr[][] = {{1, 2, 3}, {2, 5, 6}, {7, 8, 13}}, X = 1, Y = 6
Salida: 0
Explicación: X = 1 es presente en la fila 0 (considerando 0 – indexación) y Y = 6 está en la fila 2.
Ambas filas tienen ‘2’ en común, ambas son adyacentes y hay 0 filas en el medio.Entrada: arr[][] = {{1, 2, 3}, {2, 5, 6}, {3, 7, 13}}, X = 2, Y = 6
Salida: 0
Explicación: Ambos números son en la misma fila.Entrada: arr[][] = {{1, 2, 3}, {2, 5, 6}, {3, 7, 13}}, X = 2, Y = 8
Salida: -1
Explicación: No hay posible combinación de filas adyacentes entre la fila que contiene X y la fila que contiene Y.Entrada: arr[][] = {{1, 2, 3, 21}, {1, 11, 12, 25}, {12, 13, 14, 7}, {3, 5, 6, 7}, { 6, 8, 9, 10}}, X = 1, Y = 9
Salida: 1
Explicación: Una posible combinación de filas adyacentes es 0 -> 1 -> 2 -> 3 -> 4 que tiene 3 filas adyacentes entre ellas.
Otra forma posible 1 -> 2 -> 3 -> 4 que tiene 2 filas adyacentes entre ellas.
La ruta que tiene filas mínimas sería 0 -> 4 -> 5 que tiene solo 1 fila en el medio.
Enfoque: el problema dado se puede resolver usando la ruta más corta en un gráfico no ponderado que usa el algoritmo BFS .
- Cree un gráfico no ponderado donde cada Node represente una fila.
- Dos Nodes de este gráfico están conectados si comparten al menos 1 número común entre ellos.
- Ejecute el bucle for externo desde i = 0 hasta N , donde N es el número de filas.
- Ejecute un ciclo interno de j = i + 1 a N .
- Conecte la fila ‘i’ y la fila ‘j’ si hay algo común en ambas filas.
- Ejecute el bucle for externo desde i = 0 hasta N , donde N es el número de filas.
- Ahora el problema se reduce a encontrar el camino más corto desde el Node que tiene X hasta el Node que tiene Y.
- Vuelva a ejecutar otro bucle anidado y almacene las filas que tienen X en una cola para usarlas para BFS.
- Además, al almacenar todas las filas que tienen Y, se usará para detectar si se alcanza o no el Node que tiene el número objetivo.
- Si el Node actual en el recorrido BFS del gráfico tiene una Y, devuelva el número de aristas recorridas: 1.
- Si BFS está en exceso, devuelve -1, no hay combinación posible de filas adyacentes entre ambas filas.
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ program to implement the approach #include <bits/stdc++.h> using namespace std; // class to represent node in queue class Node { public: int rowNo; int edgesTravelled; Node(int r, int e) { this->rowNo = r; this->edgesTravelled = e; } }; // function to check connection b/w two rows bool shareCommon(vector<int>& i, vector<int>& j) { // adding all elements of larger array to hashset then // iterating other array set<int> row1; if (i.size() > j.size()) { for (int idx = 0; idx < i.size(); idx++) { row1.insert(i[idx]); } for (int idx = 0; idx < j.size(); idx++) { if (row1.count(j[idx])) return true; } } else { for (int idx = 0; idx < j.size(); idx++) { row1.insert(j[idx]); } for (int idx = 0; idx < i.size(); idx++) { if (row1.count(i[idx])) return true; } } return false; } void minRowsBetweenXY(vector<vector<int> >& arr, int X, int Y) { // No. of rows int N = arr.size(); if (X == Y) { cout << 0; return; } // constructing graph: vector<vector<int> > graph(N); for (int i = 0; i < N; i++) { for (int j = i + 1; j < N; j++) { // if row i and j share something in common then // connect row i and j if (shareCommon(arr[i], arr[j])) { graph[i].push_back(j); graph[j].push_back(i); } } } // queue for BFS queue<Node> q; // visited array for bfs vector<bool> visited(N, false); // Set to store rows having Y set<int> targetRows; for (int i = 0; i < N; i++) { for (int j = 0; j < arr[i].size(); j++) { if (arr[i][j] == Y) { targetRows.insert(i); } if (arr[i][j] == X && !visited[i]) { q.push(Node(i, 0)); // q.add(new Node(i, 0)); visited[i] = true; } } } // using bfs algorithm: while (q.size() > 0) { Node rm = q.front(); q.pop(); // if the removed node is in the target row then // return if (targetRows.count(rm.rowNo)) { if (rm.edgesTravelled == 0) { cout << 0; return; } cout << rm.edgesTravelled - 1; return; } // adding neighbouring nodes for (int nbr : graph[rm.rowNo]) { if (!visited[nbr]) { int edgesTravelledBeforeNbr = rm.edgesTravelled; q.push( Node(nbr, 1 + edgesTravelledBeforeNbr)); visited[nbr] = true; } } } // if bfs over => path not possible cout << -1; } // Driver code int main() { vector<vector<int> > arr = { { 1, 2, 3, 21 }, { 1, 11, 12, 25 }, { 12, 13, 14, 7 }, { 3, 5, 6, 7 }, { 6, 8, 9, 10 } }; int X = 1; int Y = 9; minRowsBetweenXY(arr, X, Y); return 0; } // This code is contributed by abhishekghoshindia.
Java
// Java program to find minimum adjacent // rows between rows containing X and Y import java.util.*; class GFG { static void minRowsBetweenXY(int[][] arr, int X, int Y) { // No. of rows int N = arr.length; if (X == Y) { System.out.println(0); return; } // constructing graph: ArrayList<ArrayList<Integer> > graph = new ArrayList<ArrayList<Integer> >(); for (int i = 0; i < N; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < N; i++) { for (int j = i + 1; j < N; j++) { // if row i and j share // something in common // then connect row i and j if (shareCommon(arr[i], arr[j])) { graph.get(i).add(j); graph.get(j).add(i); } } } // queue fo BFS Queue<Node> q = new ArrayDeque<>(); // visited array for bfs boolean[] visited = new boolean[N]; // hashset to store rows // having Y HashSet<Integer> targetRows = new HashSet<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < arr[i].length; j++) { if (arr[i][j] == Y) { targetRows.add(i); } if (arr[i][j] == X && !visited[i]) { q.add(new Node(i, 0)); visited[i] = true; } } } // using bfs algorithm: while (q.size() > 0) { Node rm = q.remove(); // if the removed node is in // the target row then return: if (targetRows.contains(rm.rowNo)) { if (rm.edgesTravelled == 0) { System.out.println(0); return; } System.out.println( rm.edgesTravelled - 1); return; } // adding neighbouring nodes for (Integer nbr : graph.get(rm.rowNo)) { if (!visited[nbr]) { int edgesTravelledBeforeNbr = rm.edgesTravelled; q.add(new Node( nbr, edgesTravelledBeforeNbr + 1)); visited[nbr] = true; } } } // if bfs over // => path not possible System.out.println(-1); } // function to check connection b/w // two rows static boolean shareCommon(int[] i, int[] j) { // adding all elements // of larger array to hashset // then iterating other array HashSet<Integer> row1 = new HashSet<>(); if (i.length > j.length) { for (int idx = 0; idx < i.length; idx++) { row1.add(i[idx]); } for (int idx = 0; idx < j.length; idx++) { if (row1.contains(j[idx])) return true; } } else { for (int idx = 0; idx < j.length; idx++) { row1.add(j[idx]); } for (int idx = 0; idx < i.length; idx++) { if (row1.contains(i[idx])) return true; } } return false; } // class to represent node in queue static class Node { int rowNo; int edgesTravelled; Node(int r, int e) { this.rowNo = r; this.edgesTravelled = e; } } // driver code public static void main(String[] args) { int[][] arr = { { 1, 2, 3, 21 }, { 1, 11, 12, 25 }, { 12, 13, 14, 7 }, { 3, 5, 6, 7 }, { 6, 8, 9, 10 } }; int X = 1; int Y = 9; minRowsBetweenXY(arr, X, Y); } }
C#
// C# program to find minimum adjacent // rows between rows containing X and Y using System; using System.Collections.Generic; public class GFG { // class to represent node in queue public class Node { public int rowNo; public int edgesTravelled; public Node(int r, int e) { this.rowNo = r; this.edgesTravelled = e; } } public static int[] GetRow(int[,] matrix, int row) { var rowLength = matrix.GetLength(1); var rowVector = new int[rowLength]; for (var i = 0; i < rowLength; i++) rowVector[i] = matrix[row, i]; return rowVector; } static void minRowsBetweenXY(int[,] arr, int X, int Y) { // No. of rows int N = arr.GetLength(0); if (X == Y) { Console.WriteLine(0); return; } // constructing graph: List<List<int> > graph = new List<List<int> >(); for (int i = 0; i < N; i++) { graph.Add(new List<int>()); } for (int i = 0; i < N; i++) { for (int j = i + 1; j < N; j++) { // if row i and j share // something in common // then connect row i and j int[] t1 = GetRow(arr,i); int[] t2 = GetRow(arr,j); if (shareCommon(t1,t2)) { graph[i].Add(j); graph[j].Add(i); } } } // queue fo BFS List<Node> q = new List<Node>(); // visited array for bfs bool[] visited = new bool[N]; // hashset to store rows // having Y HashSet<int> targetRows = new HashSet<int>(); for (int i = 0; i < N; i++) { for (int j = 0; j < arr.GetLength(1); j++) { if (arr[i,j] == Y) { targetRows.Add(i); } if (arr[i,j] == X && !visited[i]) { q.Add(new Node(i, 0)); visited[i] = true; } } } // using bfs algorithm: while (q.Count > 0) { Node rm = q[0]; q.RemoveAt(0); // if the removed node is in // the target row then return: if (targetRows.Contains(rm.rowNo)) { if (rm.edgesTravelled == 0) { Console.WriteLine(0); return; } Console.WriteLine( rm.edgesTravelled - 1); return; } // adding neighbouring nodes foreach (int nbr in graph[rm.rowNo]) { if (!visited[nbr]) { int edgesTravelledBeforeNbr = rm.edgesTravelled; q.Add(new Node( nbr, edgesTravelledBeforeNbr + 1)); visited[nbr] = true; } } } // if bfs over // => path not possible Console.WriteLine(-1); } // function to check connection b/w // two rows static bool shareCommon(int[] i, int[] j) { // adding all elements // of larger array to hashset // then iterating other array HashSet<int> row1 = new HashSet<int>(); if (i.Length > j.Length) { for (int idx = 0; idx < i.Length; idx++) { row1.Add(i[idx]); } for (int idx = 0; idx < j.Length; idx++) { if (row1.Contains(j[idx])) return true; } } else { for (int idx = 0; idx < j.Length; idx++) { row1.Add(j[idx]); } for (int idx = 0; idx < i.Length; idx++) { if (row1.Contains(i[idx])) return true; } } return false; } // driver code public static void Main(String[] args) { int[,] arr = { { 1, 2, 3, 21 }, { 1, 11, 12, 25 }, { 12, 13, 14, 7 }, { 3, 5, 6, 7 }, { 6, 8, 9, 10 } }; int X = 1; int Y = 9; minRowsBetweenXY(arr, X, Y); } } // This code is contributed by shikhasingrajput
Javascript
<script> // Javascript code to implement the approach // class to represent node in queue class Node { constructor(r, e) { this.rowNo = r; this.edgesTravelled = e; } } // function to check connection b/w two rows function shareCommon(i, j) { // adding all elements of larger array to hashset then // iterating other array var row1 = new Set() if (i.length > j.length) { for (let idx = 0; idx < i.length; idx++) { row1.add(i[idx]) } for (let idx = 0 ; idx < j.length ; idx++) { if (row1.has(j[idx])){ return true } } } else { for (let idx = 0; idx < j.length; idx++) { row1.add(j[idx]); } for (let idx = 0; idx < i.length; idx++) { if (row1.has(i[idx])){ return true } } } return false; } function minRowsBetweenXY(arr, X, Y) { // No. of rows let N = arr.length; if (X == Y) { console.log(0) return; } // constructing graph: var graph = Array(N) for(let i = 0 ; i < N ; i++){ graph[i] = Array() } for (let i = 0; i < N; i++) { for (let j = i + 1; j < N; j++) { // if row i and j share something in common then // connect row i and j if (shareCommon(arr[i], arr[j])) { graph[i].push(j); graph[j].push(i); } } } // queue for BFS var q = Array() // visited array for bfs var visited = Array(N); for(let i = 0 ; i < N ; i++){ visited[i] = false } // Set to store rows having Y var targetRows = new Set() for (let i = 0; i < N; i++) { for (let j = 0; j < arr[i].length; j++) { if (arr[i][j] == Y) { targetRows.add(i) } if (arr[i][j] == X && !visited[i]) { q.push(new Node(i, 0)) // q.add(new Node(i, 0)); visited[i] = true } } } // using bfs algorithm: while (q.length > 0) { var rm = q[0] q.shift() // if the removed node is in the target row then // return if (targetRows.has(rm.rowNo)) { if (rm.edgesTravelled == 0) { console.log(0) return; } console.log(rm.edgesTravelled - 1) return; } // adding neighbouring nodes for(let i = 0 ; i < graph[rm.rowNo].length ; i++){ var nbr = graph[rm.rowNo][i] if (!visited[nbr]) { let edgesTravelledBeforeNbr = rm.edgesTravelled; q.push(new Node(nbr, 1 + edgesTravelledBeforeNbr)); visited[nbr] = true; } } } // if bfs over => path not possible console.log(-1) } // Driver code var arr = [ [ 1, 2, 3, 21 ], [ 1, 11, 12, 25 ], [ 12, 13, 14, 7 ], [ 3, 5, 6, 7 ], [ 6, 8, 9, 10 ] ]; var X = 1; var Y = 9; minRowsBetweenXY(arr, X, Y); // This code is contributed by subhamgoyal2014. </script>
1
Complejidad de Tiempo: O(N 2 + N * M)
Espacio Auxiliar: O(N 2 + M)
Publicación traducida automáticamente
Artículo escrito por karandeep1234 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA