GFG App
Open App
Browser
Continue

# Minimum count of rows between rows containing X and Y respectively

Given a Grid of size NxM, and two integers X and Y, the task is to count the minimum number of rows between the row containing X and the row containing Y in such a way that the adjacent rows in between them have at least one element in common. Multiple occurrences of a number are allowed in the grid. In other words, two rows are said to be adjacent if they have at least one element in common.

Examples:

Input: arr[][] = {{1, 2, 3}, {2, 5, 6}, {7, 8, 13}}, X = 1, Y = 6
Output: 0
Explanation: X = 1 is present in row 0 (considering 0 – indexing) and Y = 6 is in row 2.
Both the rows have ‘2’ in common both of them are adjacent and there are 0 rows in between.

Input: arr[][] = {{1, 2, 3}, {2, 5, 6}, {3, 7, 13}}, X = 2, Y = 6
Output: 0
Explanation: Both the numbers are in same row.

Input: arr[][] = {{1, 2, 3}, {2, 5, 6}, {3, 7, 13}}, X = 2, Y = 8
Output: -1
Explanation: There is no possible combination of adjacent rows between row containing X and row containing Y.

Input: 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
Output: 1
Explanation: One possible combination of adjacent rows is 0 -> 1 -> 2 -> 3 -> 4 which has 3 adjacent rows between them.
Another possible way 1 -> 2 -> 3 -> 4 which has 2 adjacent rows between them.
The path which have minimum rows would be 0 -> 4 -> 5 which has only 1 row in-between.

Approach:  The given problem can be solved by using the shortest path in an unweighted graph that uses BFS Algorithm.

• Create an unweighted graph where each node represents a row.
• Two nodes of this graph are connected if they share at least 1 common number between them.
• Run outer for loop from i = 0 to N where N is the number of rows.
• Run an inner loop from j = i + 1 to N .
• Connect row ‘i’ and row ‘j’ if there is something common in both rows.
• Now the problem is reduced to finding the shortest path from the node having X to the node having Y.
• Again run another nested loop and store the rows which have X in a queue to be used for BFS.
• Also, storing all the rows which have Y, it will be used to detect if the node has target number is reached or not.
• If the current node in the BFS traversal of the graph has a Y, return the number of edges traveled – 1.
• If BFS is over return -1 as there is no possible combination of adjacent rows between both rows.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement the approach` `#include ` `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 >& arr, ``int` `X,` `                      ``int` `Y)` `{` `  ``// No. of rows` `  ``int` `N = arr.size();` `  ``if` `(X == Y) {` `    ``cout << 0;` `    ``return``;` `  ``}` `  ``// constructing graph:` `  ``vector > 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 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 > 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 > graph` `            ``= ``new` `ArrayList >();` `        ``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 q = ``new` `ArrayDeque<>();` `        ``// visited array for bfs` `        ``boolean``[] visited = ``new` `boolean``[N];`   `        ``// hashset to store rows` `        ``// having Y` `        ``HashSet 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 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);` `    ``}` `}`

## Python3

 `# Python code to implement the approach`   `# class to represent node in queue` `class` `Node:` `    ``def` `__init__(``self``, r, e):` `        ``self``.rowNo ``=` `r` `        ``self``.edgesTravelled ``=` `e`   `# function to check connection b/w two rows` `def` `shareCommon(i, j):` `  `  `    ``# adding all elements of larger array to hashset then` `    ``# iterating other array` `    ``row1 ``=` `set``()` `    ``if` `(``len``(i) > ``len``(j)):` `        ``for` `idx ``in` `range``(``len``(i)):` `            ``row1.add(i[idx])`   `        ``for` `idx ``in` `range``(``len``(j)):` `            ``if` `(j[idx] ``in` `row1):` `                ``return` `True`   `    ``else``:` `        ``for` `idx ``in` `range``(``len``(j)):` `            ``row1.add(j[idx])`   `        ``for` `idx ``in` `range``(``len``(i)):` `            ``if` `(i[idx] ``in` `row1):` `                ``return` `True`   `    ``return` `False`     `def` `minRowsBetweenXY(arr, X, Y):` `    ``# No. of rows` `    ``N ``=` `len``(arr)` `    ``if` `(X ``=``=` `Y):` `        ``print``(``0``)` `        ``return`   `    ``# constructing graph:` `    ``graph ``=` `[``0``] ``*` `N` `    ``for` `i ``in` `range``(N):` `        ``graph[i] ``=` `[]`   `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(i ``+` `1``, N):` `            ``# if row i and j share something in common then` `            ``# connect row i and j` `            ``if` `(shareCommon(arr[i], arr[j])):` `                ``graph[i].append(j)` `                ``graph[j].append(i)`   `    ``# queue for BFS` `    ``q ``=` `[]` `    ``# visited array for bfs` `    ``visited ``=` `[``0``] ``*` `N` `    ``for` `i ``in` `range``(N):` `        ``visited[i] ``=` `False`   `    ``# Set to store rows having Y` `    ``targetRows ``=` `set``()`   `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(``len``(arr[i])):` `            ``if` `(arr[i][j] ``=``=` `Y):` `                ``targetRows.add(i)`   `            ``if` `(arr[i][j] ``=``=` `X ``and` `not` `visited[i]):` `                ``q.append(Node(i, ``0``))` `                ``# q.add(new Node(i, 0));` `                ``visited[i] ``=` `True`   `    ``# using bfs algorithm:` `    ``while` `(``len``(q) > ``0``):` `        ``rm ``=` `q[``0``]` `        ``q.pop(``0``)`   `        ``# if the removed node is in the target row then` `        ``# return` `        ``if` `(rm.rowNo ``in` `targetRows):` `            ``if` `(rm.edgesTravelled ``=``=` `0``):` `                ``print``(``0``)` `                ``return`   `            ``print``(rm.edgesTravelled ``-` `1``)` `            ``return`   `        ``# adding neighbouring nodes` `        ``for` `i ``in` `range``(``len``(graph[rm.rowNo])):` `            ``nbr ``=` `graph[rm.rowNo][i]` `            ``if` `(``not` `visited[nbr]):` `                ``edgesTravelledBeforeNbr ``=` `rm.edgesTravelled` `                ``q.append(Node(nbr, ``1` `+` `edgesTravelledBeforeNbr))` `                ``visited[nbr] ``=` `True`   `    ``# if bfs over => path not possible` `    ``print``(``-``1``)`     `# Driver code` `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` `minRowsBetweenXY(arr, X, Y)`   `# This code is contributed by Saurabh Jaiswal`

## 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 > graph` `      ``= ``new` `List >();` `    ``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 q = ``new` `List();` `    ``// 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

 ``

Output:

`1`

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

My Personal Notes arrow_drop_up