200. 岛屿数量(BFS+并查集)
200. 岛屿数量
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为'0'
或'1'
解法一:(BFS)
1 class Solution { 2 public: 3 static constexpr int g_direciton[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; 4 void bfs(const vector<vector<char>> &grid, int x, int y, vector<vector<bool>> &visited) { 5 int row = grid.size(); 6 int col = grid[0].size(); 7 queue<std::pair<int, int>> q; 8 q.push(make_pair(x, y)); 9 visited[x][y] = true; 10 while (!q.empty()) { 11 int size = q.size(); 12 for (int i = 0; i < size; i++) { 13 std::pair<int, int> tmp = q.front(); 14 q.pop(); 15 for (int j = 0; j < 4; j++) { 16 int xNext = tmp.first + g_direciton[j][0]; 17 int yNext = tmp.second + g_direciton[j][1]; 18 if ((xNext >= 0 && xNext < row) && (yNext >= 0 && yNext < col) && 19 !visited[xNext][yNext] && (grid[xNext][yNext] == '1')) { 20 q.push(make_pair(xNext, yNext)); 21 visited[xNext][yNext] = true; 22 } 23 } 24 } 25 } 26 } 27 int numIslands(vector<vector<char>>& grid) { 28 if (grid.size() == 0 || grid[0].size() == 0) { 29 return 0; 30 } 31 int row = grid.size(); 32 int col = grid[0].size(); 33 vector<vector<bool>> visited(row, vector<bool>(col, false)); 34 int cnt = 0; 35 for (int i = 0; i < row; i++) { 36 for (int j = 0; j < col; j++) { 37 if (grid[i][j] == '0') { 38 continue; 39 } 40 if (visited[i][j]) { 41 continue; 42 } 43 bfs(grid, i, j, visited); 44 cnt++; 45 } 46 } 47 return cnt; 48 } 49 };
解法二:(并查集)
1 class UnionFind { 2 public: 3 void initUnionFind(vector<vector<char>> &grid) { 4 int row = grid.size(); 5 int col = grid[0].size(); 6 int n = row * col; 7 parent.resize(n); 8 cnt = 0; 9 for (int i = 0; i < row; i++) { 10 for (int j = 0; j < col; j++) { 11 int index = i * col + j; // 二维转一维 12 parent[index] = index; 13 if (grid[i][j] == '1') { 14 cnt++; // 初始时岛屿的数量为陆地数量(数值为1) 15 } 16 } 17 } 18 } 19 int findRoot(int x) { 20 if (parent[x] == x) { 21 return parent[x]; 22 } 23 parent[x] = findRoot(parent[x]); // 递归找到x的根节点 24 return parent[x]; 25 } 26 void unify(int x, int y) { 27 int xRoot = findRoot(x); 28 int yRoot = findRoot(y); 29 if (xRoot == yRoot) { 30 return; 31 } 32 parent[xRoot] = yRoot; 33 cnt--; 34 } 35 int getConnectedCnt() { 36 return cnt; 37 } 38 private: 39 vector<int> parent; 40 int cnt; // 连通分量数 41 }; 42 class Solution : UnionFind { 43 public: 44 int numIslands(vector<vector<char>>& grid) { 45 if (grid.size() == 0 || grid[0].size() == 0) { 46 return 0; 47 } 48 initUnionFind(grid); 49 int row = grid.size(); 50 int col = grid[0].size(); 51 for (int i = 0; i < row; i++) { 52 for (int j = 0; j < col; j++) { 53 int index = i * col + j; 54 if (grid[i][j] == '1') { 55 // 左右为1的岛屿合并 56 if ((i + 1 < row) && grid[i + 1][j] == '1') { 57 unify(index, (i + 1) * col + j); 58 } 59 // 上下为1的岛屿合并 60 if ((j + 1 < col) && grid[i][j + 1] == '1') { 61 unify(index, i * col + j + 1); 62 } 63 } 64 } 65 } 66 return getConnectedCnt(); 67 } 68 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理