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.

Example

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的更多相关文章

  1. [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 ...

  2. [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 ...

  3. [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 ...

  4. 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 ...

  5. 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  ...

  6. [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 ...

  7. 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 ...

  8. LeetCode 305. Number of Islands II

    原题链接在这里:https://leetcode.com/problems/number-of-islands-ii/ 题目: A 2d grid map of m rows and n column ...

  9. [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 ...

随机推荐

  1. java实验项目报告

            JAVA课程项目报告   题目:利用java实现一个时钟的小程序 姓名:王国梁 班级:计科13-2 学号:201303011200         利用JAVA实现一个时钟的小程序 1 ...

  2. div z-index无论设置多高都不起作用

    这种情况发生的条件有三个: 1.父标签position属性为relative: 2.当前标签无position属性(relative,absolute,fixed): 3.当前标签含有浮动(float ...

  3. Ubuntu安装eclipse,并创建桌面快捷方式

    系统:Ubuntu 16.04 JDK版本:1.8.0_121 Ubuntu下安装JDK配置环境变量可见我的这篇文章   http://www.cnblogs.com/AloneZ/p/Ubuntu1 ...

  4. ORM的详解

    有很多小伙伴都不太理解ORM是什么,其实不用想象的那么复杂.我们先根据3W1H去理解. who:首先ORM可以立即为(Object/Relation Mapping): 对象/关系映射 what:其次 ...

  5. MongoDB入门 和nodejs操作

    简介 MongoDB 开源,高性能的NoSQL数据库:支持索引.集群.复制和故障转移.各种语言的驱动程序:高伸缩性: NoSQL毕竟还处于发展阶段,也有说它的各种问题的:http://coolshel ...

  6. C++ main()函数及其参数

    1.首先,想想C/C++在main函数之前和之后会做些什么? 我们看看底层的汇编代码: __start: : init stack; init heap; open stdin; open stdou ...

  7. 模拟事件【JavaScript高级程序设计第三版】

    事件,就是网页中某个特别值得关注的瞬间.事件经常由用户操作或通过其他浏览器功能来触发.但很少有人知道,也可以使用JavaScript 在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一样 ...

  8. 伪数组(arguments及字符串)转数组的方法 贼简单

    超简单的伪数组转数组的方法, 简单到令人发指! (这里伪数组使用arguments) 1.使用 Array.prototype.slice Array.prototype.slice.call(arg ...

  9. 菜菜小问题——python中print函数 以及单引号、双引号、三引号

    直接面对——引号,就是为了保证打印出来的东东符合预期 如:print("小菜菜") 结果是: .================1========================= ...

  10. Java多线程与线程同步

    六.多线程,线程,同步 ①概念: 并行:指两个或多个在时间同一时刻发生(同时发生) 并发:指两个或多个事件在同一时间段内发生 具体概念: 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多 ...