Number of Islands I & II
Given a boolean 2D matrix, find the number of islands.
Notice
0 is represented as the sea, 1 is represented as the island. If two 1 is adjacent, we consider them in the same island. We only consider up/down/left/right adjacent.
Given graph:
[
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1]
]
return 3.
分析:
从第一个数到最后一个数,如果遇到1,则island count 加1, 并且不断递归去寻找周围的1。
public class Solution {
public int numIslands(char[][] grid) {
int count = ;
if (grid == null || grid.length == ) return count;
int m = grid.length, n = grid[].length;
boolean[][] visited = new boolean[m][n];
for (int i = ; i < m; i++) {
for (int j = ; j < n; j++) {
if (!visited[i][j] && grid[i][j] == '') {
count++;
flood(i, j, grid, visited);
}
}
}
return count;
}
private void flood(int i, int j, char[][] grid, boolean[][] visited) {
if (i < || i >= grid.length || j < || j >= grid[].length) return;
if (grid[i][j] == '' || visited[i][j]) return;
visited[i][j] = true;
flood(i + , j, grid, visited);
flood(i - , j, grid, visited);
flood(i, j + , grid, visited);
flood(i, j - , grid, visited);
}
}
Follow up:
Find the perimeter of the island. Answer: find the # of 1 which is next to 0.
Number of Islands II
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation which turns the water at position (row, col) into a land. Given a list of positions to operate, count the number of islands after each addLand operation. 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.
Example:
Given m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]].
Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 >represents land).
0 0 0
0 0 0
0 0 0
Operation #1: addLand(0, 0) turns the water at grid0 into a land.
1 0 0
0 0 0 Number of islands = 1
0 0 0
Operation #2: addLand(0, 1) turns the water at grid0 into a land.
1 1 0
0 0 0 Number of islands = 1
0 0 0
Operation #3: addLand(1, 2) turns the water at grid1 into a land.
1 1 0
0 0 1 Number of islands = 2
0 0 0
Operation #4: addLand(2, 1) turns the water at grid2 into a land.
1 1 0
0 0 1 Number of islands = 3
0 1 0
We return the result as an array: [1, 1, 2, 3]
分析:https://segmentfault.com/a/1190000004197552
很典型的union-find题。因为这里是动态的增加land,要能随时求出有多少个island,最简单的方法就是union-find。我们可以定义一个counter, 每增加一个land, 增加counter, 然后我们搜索那个land邻居区域,发现root不一样的话,意味着可以union, 每union一次,意味着两个island合并成一个,减小counter, 统计最终的counter值,即是增加land后的最终island的个数。
为了减小时间复杂度,代码实现是QuickUnion + Path Compression, Path Compression目的是为了调整树的高度,保持很平的树,而不是越来越高,这样找root不会出现worst case.
public class Solution {
public List<Integer> numIslands2(int m, int n, int[][] positions) {
int[] id = new int[m * n]; // 表示各个index对应的root
Arrays.fill(id, -); // 初始化root为-1,用来标记water, 非-1表示land
List<Integer> res = new ArrayList<>();
int count = ; // 记录island的数量
int[][] dirs = { { -, }, { , }, { , }, { , - } };
for (int i = ; i < positions.length; i++) {
count++;
int index = positions[i][] * n + positions[i][];
id[index] = index; // root初始化
for (int j = ; j < dirs.length; j++) {
int x = positions[i][] + dirs[j][];
int y = positions[i][] + dirs[j][];
if (x >= && x < m && y >= && y < n && id[x * n + y] != -) {
int root = root(id, x * n + y); // this is the root of the neibor's islands
// 发现root不等的情况下,才union, 同时减小count。注意,一定要用当前index作为新的root,这样才能保证相连的岛是同一个root。
if (root != index) {
id[root] = index; // set the neighbor's island's root to be the new island index
count--;
}
}
}
res.add(count);
}
return res;
}
public int root(int[] id, int i) {
while (i != id[i]) {
id[i] = id[id[i]]; // 优化,为了减小树的高度
i = id[i];
}
return i;
}
}
Number of Islands I & II的更多相关文章
- [LeetCode] Number of Islands II 岛屿的数量之二
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- [LeetCode] 305. Number of Islands II 岛屿的数量之二
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- [LeetCode] Number of Islands II
Problem Description: A 2d grid map of m rows and n columns is initially filled with water. We may pe ...
- Leetcode: Number of Islands II && Summary of Union Find
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- 305. Number of Islands II
题目: A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand ...
- [Swift]LeetCode305. 岛屿的个数 II $ Number of Islands II
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- LeetCode – Number of Islands II
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
- LeetCode 305. Number of Islands II
原题链接在这里:https://leetcode.com/problems/number-of-islands-ii/ 题目: A 2d grid map of m rows and n column ...
- [LeetCode] 305. Number of Islands II 岛屿的数量 II
A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...
随机推荐
- 英语学习APP
第一部分 调研, 评测 下载并使用,描述最简单直观的个人第一次上手体验. 界面高大上,看起来很美观,是个不错的英语学习软件.我很喜欢. 2.按照<构建之法>13.1节描述的 bug 定义, ...
- KindEditor:Ajax提交表单时获取不到HTML内容
当用Ajax提交表单时,KindEditor的内容获取不到,HTML数据获取不了 原因:当ajax提交时,KindEdito的HTML数据还没有同步到表单中来,那怎么去获取HTML数据呢? ----- ...
- ElasticSearch搜索实例含高亮显示及搜索的特殊字符过滤
应用说明见代码注解. 1.简单搜索实例展示: public void search() throws IOException { // 自定义集群结点名称 String clusterName = & ...
- 12th final 发布评价II
1.约跑App——nice!:用户界面很是赏心悦目,给人一种很放松的感觉,与App的主题很配合,同时也在本周内把同学提出的bug都很好地完善了,而且采用了摄像头进行发布,整个发布过程清晰明朗不少.把约 ...
- .NET获取文件的MIME类型(Content Type)
第一种:这种获取MIME类型(Content Type)的方法需要在.NET 4.5之后才能够支持,但是非常简单. 优点:方便快捷 缺点:只能在.NET 4.5之后使用 public FileResu ...
- BZOJ1018 SHOI2008堵塞的交通(线段树)
动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...
- ubuntu修改用户名并修改home对应的目录名
1.新建一个新的用户user2 sudo adduser temporary sudo adduser temporary sudo 2.从user1 logout.进入新建用户user2,修改use ...
- 【Treap 例题】神秘岛(island)
神秘岛(island) 题目描述: 除了敲代码和撩妹,旅行是cxw123 的第三爱好.他来到了澳大利亚东北部的大宝礁,在这里,有一个隔绝人世的神秘岛,这个岛不同于附近其他的珊瑚岛,它的生长速度极快,甚 ...
- IIS应用程序池相关问题及连接池已满的解决方法
关于应用程序池 在 IIS 6.0 中,引入了应用程序池,应用程序池是将一个或多个应用程序链接到一个或多个工作进程集合的配置.因为应用程序池中的应用程序与其他应用程序被工作进程边界分隔 ...
- c++并发编程之创建线程
以boost为例.boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象: (2)explicit thread(const boost::functi ...