📌  相关文章
📜  分别包含 X 和 Y 的行之间的最小行数

📅  最后修改于: 2022-05-13 01:56:04.965000             🧑  作者: Mango

分别包含 X 和 Y 的行之间的最小行数

给定一个大小为NxMGrid和两个整数XY ,任务是计算包含X的行和包含Y的行之间的最小行数,使得它们之间的相邻行至少有一个元素共同点。网格中允许多次出现一个数字。换句话说,如果两行至少有一个共同的元素,则称它们是相邻的。

例子:

方法:给定的问题可以通过使用BFS 算法的未加权图中的最短路径来解决

  • 创建一个未加权图,其中每个节点代表一行。
  • 如果该图的两个节点之间共享至少 1 个公共数字,则它们是连接的。
    • i = 0 到 N运行外部 for 循环,其中N是行数。
      • 运行从j = i + 1 到 N的内部循环。
      • 如果两行有共同点,则连接“i”行和“j”行。
  • 现在问题简化为找到从具有 X 的节点到具有 Y 的节点的最短路径。
  • 再次运行另一个嵌套循环并将具有 X 的行存储在队列中以用于BFS。
  • 此外,存储所有具有 Y 的行,它将用于检测节点是否达到目标编号。
  • 如果图的BFS 遍历中的当前节点有 Y,则返回经过的边数 - 1。
  • 如果 BFS 结束,则返回-1 ,两行之间没有可能的相邻行组合。

下面是上述方法的实现:

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);
    }
}


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());
    }
 
    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 targetRows = new HashSet();
 
    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 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;
  }
 
 
  // 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



输出:
1

时间复杂度: O(N 2 + N * M)
辅助空间: O(N 2 + M)