题目
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
数据
示例 1:输入:11110110101100000000输出: 1示例 2:输入:11000110000010000011输出: 3解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成
解题思路
used :哈希集合,用于判断节点是否入过队列;当节点加入队列时,同时将节点信息加入哈希集numIslands :两层循环判断是否节点已经加入过队列,如果没有: nums++ ,把当前节点的下标传入 BFS ,加入哈希集 usedBFS :创建队列来进行广度优先搜索:队列头部的上下左右四个相邻节点是否满足条件,满足则加入队列和 used ,然后队列头部节点出队
代码
package DataStructure;import java.util.HashSet;import java.util.LinkedList;import java.util.Queue;import java.util.Set;public class BFS {/*** Given a 2d grid map of '1's (land) and '0's (water), count the number of islands.* An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically.* You may assume all four edges of the grid are all surrounded by water.* Input:* 11110* 11010* 11000* 00000* Output: 1** @param grid* @return the num of lands*/public int numIslands(char[][] grid) {Set<Node> used = new HashSet<>(); //用于判定节点是否加入过队列int nums = 0;for (int i = 0; i < grid.length; i++) { // 遍历每个节点,如果节点为1并且不在哈希集中,则nums++,并把节点信息传给BFSfor (int j = 0; j < grid[0].length; j++) {if (grid[i][j] == '1' && !used.contains(new Node(i, j))) {nums++;used.add(new Node(i, j));BFS(grid, i, j, used);}}}return nums;}/*** 为哈希集 used 配置每个节点的信息,存储节点下标*/class Node {int x, y;public Node(int i, int j) {x = i;y = j;}@Overridepublic boolean equals(Object obj) {if (!(obj instanceof Node))return false;if (obj == this)return true;return this.x == ((Node) obj).x && this.y == ((Node) obj).y;}@Overridepublic int hashCode() {return x + y;}}/*** 对于每个队列头节点,遍历其相邻的节点,将所有相连节点加入队列** @param grid* @param x* @param y* @param used*/public void BFS(char[][] grid, int x, int y, Set<Node> used) {Queue<Node> queue = new LinkedList<>();queue.add(new Node(x, y));int length = grid.length;int width = grid[0].length;while (!queue.isEmpty()) { //相邻节点满足没有加入过队列且为陆地则入队,入集合used// 右边相邻节点int i = queue.peek().x, j = queue.peek().y + 1;if (j < width && grid[i][j] == '1' && !used.contains(new Node(i, j))) { //如果右边相邻的是陆地并且不在哈希集中,加入队列,加入哈希集queue.add(new Node(i, j));used.add(new Node(i, j));}// 下面相邻节点i = queue.peek().x + 1;j = queue.peek().y;if (i < length && grid[i][j] == '1' && !used.contains(new Node(i, j))) { //如果下面相邻的是陆地并且不在哈希集中,加入队列,加入哈希集queue.add(new Node(i, j));used.add(new Node(i, j));}//左边相邻节点i = queue.peek().x;j = queue.peek().y - 1;if (j >= 0 && grid[i][j] == '1' && !used.contains(new Node(i, j))) {queue.add(new Node(i, j));used.add(new Node(i, j));}// 上面相邻的节点i = queue.peek().x - 1;j = queue.peek().y;if (i >= 0 && grid[i][j] == '1' && !used.contains(new Node(i, j))) {queue.add(new Node(i, j));used.add(new Node(i, j));}queue.poll();}}}
