【Leetcode】200. 岛屿数量(并查集/ BFS/ DFS)

本文介绍了一种使用并查集算法解决二维网格中岛屿数量计算问题的方法。通过将相邻的陆地进行合并操作,最后计算独立集合的数量来得出岛屿总数。详细展示了并查集的初始化、合并和查找过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

输入:

11110

11010

11000

00000

输出: 1

解题思路:

  1. DFS,记录启动DFS的次数
  2. BFS,记录启动BFS次数
  3. 并查集,对相邻陆地进行合并操作,计算集合数目

代码:并查集为例

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <string.h>
using namespace std;
/*
	给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,
	并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

*/
class Solution {
public:
	int *p;
	int row;
	int col;
	void init(int size) {  // 初始化操作
		p = new int[size];
		for (int i = 0; i < size; i++)
			p[i] = i;
	}

	void u(int node1, int node2) {  // 合并操作
		int root1 = find(node1);
		int root2 = find(node2);
		if (root1 != root2)p[root2] = root1;
	}

	bool isconnect(int node1, int node2) {
		int root1 = find(node1);
		int root2 = find(node2);
		return root1 == root2;
	}

	int find(int node) {  //查找父亲结点并进行路径压缩
		int i, j = node;
		while (p[node] != node)node = p[node];
		while (j != p[j]) {   //路径压缩
			i = j;
			j = p[j];
			p[i] = node;
		}
		return node;
	}

	int seq(int i, int j) {  //计算对应矩阵元素在一维数组中的下标
		return i * col + j;
	}

	int numIslands(vector<vector<char>>& grid) {
		int ans = 0;
		if (grid.size() == 0 || grid[0].size() == 0)return 0;
		row = grid.size();
		col = grid[0].size();
		init(row*col);
		for(int i = 0; i < row; i++)
			for (int j = 0; j < col; j++) {
				if (grid[i][j] == '1') {  //对相邻陆地进行合并操作
					int temp = seq(i, j);
					if (i > 0 && grid[i - 1][j] == '1')u(temp, seq(i - 1, j));
					if (i < row - 1 && grid[i + 1][j] == '1')u(temp, seq(i + 1, j));
					if (j > 0 && grid[i][j - 1] == '1')u(temp, seq(i, j - 1));
					if (j < col - 1 && grid[i][j + 1] == '1')u(temp, seq(i, j + 1));
				}
			}

		for (int i = 0; i < row; i++)     
			for (int j = 0; j < col; j++) {
				int temp = seq(i, j);
				if (grid[i][j] == '1'&&p[temp] == temp)ans++;    //计算岛屿数量
			}
		return ans;
	}
};

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值