在 C++ 中使用不相交集查找岛屿的数量

在这个问题中,我们得到一个二维二进制矩阵。我们的任务是使用 DFS 查找岛屿的数量

Island是矩阵中 1 个或多个连接的 1 的接地。

让我们举个例子来理解这个问题,

输入

bin[][] = {{ 1 0 0 0}

   {0 1 0 1}

   {0 0 0 0}

   {0 0 1 0}}

输出

3

解释

Islands are :

   bin00 - bin11   bin13   bin32

解决方法

使用不相交集数据结构从二进制矩阵中找到岛。为了找到岛数,我们将遍历矩阵并通过检查所有 8 个邻居来合并所有相邻顶点,如果它们是 1,则将当前索引与其邻居合并。然后对矩阵进行第二次遍历,如果任何索引处的值为1,则找到它的发送。如果频率为 0,则增加到 1。

示例

程序来说明我们的解决方案的工作原理,

#include <bits/stdc++.h>

using namespace std;

class DisjointUnionSets{

   vector<int> rank, parent;

   int n;

   public:

   DisjointUnionSets(int n){

      rank.resize(n);

      parent.resize(n);

      this->n = n;

      makeSet();

   }

   void makeSet(){

      for (int i = 0; i < n; i++)

      parent[i] = i;

   }

   int find(int x){

      if (parent[x] != x){

         return find(parent[x]);

      }

      return x;

   }

   void Union(int x, int y){

      int xRoot = find(x);

      int yRoot = find(y);

      if (xRoot == yRoot)

         return;

      if (rank[xRoot] < rank[yRoot])

         parent[xRoot] = yRoot;

      else if (rank[yRoot] < rank[xRoot])

         parent[yRoot] = xRoot;

      else {

         parent[yRoot] = xRoot;

         rank[xRoot] = rank[xRoot] + 1;

      }

   }

};

int findIslandCount(vector<vector<int>> mat){

   int n = mat.size();

   int m = mat[0].size();

   DisjointUnionSets *dus = new DisjointUnionSets(n * m);

   for (int j = 0; j < n; j++){

      for (int k = 0; k < m; k++){

         if (mat[j][k] == 0)

            continue;

         if (j + 1 < n && mat[j + 1][k] == 1)

            dus->Union(j * (m) + k, (j + 1) * (m) + k);

         if (j - 1 >= 0 && mat[j - 1][k] == 1)

            dus->Union(j * (m) + k, (j - 1) * (m) + k);

         if (k + 1 < m && mat[j][k + 1] == 1)

            dus->Union(j * (m) + k, (j) * (m) + k + 1);

         if (k - 1 >= 0 && mat[j][k - 1] == 1)

            dus->Union(j * (m) + k, (j) * (m) + k - 1);

         if (j + 1 < n && k + 1 < m && mat[j + 1][k + 1] == 1)

            dus->Union(j * (m) + k, (j + 1) * (m) + k + 1);

         if (j + 1 < n && k - 1 >= 0 && mat[j + 1][k - 1] == 1)

            dus->Union(j * m + k, (j + 1) * (m) + k - 1);

         if (j - 1 >= 0 && k + 1 < m && mat[j - 1][k + 1] == 1)

            dus->Union(j * m + k, (j - 1) * m + k + 1);

         if (j - 1 >= 0 && k - 1 >= 0 && mat[j - 1][k - 1] == 1)

            dus->Union(j * m + k, (j - 1) * m + k - 1);

      }

   }

   int *c = new int[n * m];

   int islands = 0;

   for (int j = 0; j < n; j++){

      for (int k = 0; k < m; k++){

         if (mat[j][k] == 1){

            int x = dus->find(j * m + k);

            if (c[x] == 0){

               islands++;

               c[x]++;

            }

            else

            c[x]++;

         }

      }

   }

   return islands;

}

int main(void){

   vector<vector<int>> mat = {

      {1, 1, 0, 1, 0},

      {0, 1, 0, 1, 1},

      {1, 0, 0, 1, 1},

      {0, 0, 0, 0, 0},

      {1, 1, 1, 0, 1}

   };

   cout<<"二进制矩阵中的岛数为: "<<findIslandCount(mat);

}

输出结果
二进制矩阵中的岛数为: 4

以上是 在 C++ 中使用不相交集查找岛屿的数量 的全部内容, 来源链接: utcz.com/z/297097.html

回到顶部