题目:

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 = 3positions = [[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 grid[0][0] 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 grid[0][1] 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 grid[1][2] 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 grid[2][1] 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]

Challenge:

Can you do it in time complexity O(k log mn), where k is the length of the positions?

链接: http://leetcode.com/problems/number-of-islands-ii/

题解:

又是一道Union Find的经典题。这道题代码主要参考了yavinci大神。风格还是princeton Sedgewick的那一套。这里我们可以把二维的Union-Find映射为一维的Union Find。使用Quick-Union就可以完成。但这样的话Time Complexity是O(kmn)。 想要达到O(klogmn)的话可能还需要使用Weighted-Quick Union配合path compression。二刷一定要实现。

Time Complexity - O(mn * k), Space Complexity - O(mn)

public class Solution {
int[][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; public List<Integer> numIslands2(int m, int n, int[][] positions) {
List<Integer> res = new ArrayList<>();
if(m < 0 || n < 0 || positions == null) {
return res;
}
int[] id = new int[m * n]; // union find array
int count = 0;
Arrays.fill(id, -1); for(int i = 0; i < positions.length; i++) {
int index = n * positions[i][0] + positions[i][1];
if(id[index] != -1) {
res.add(count);
continue;
} id[index] = index;
count++; for(int[] direction : directions) {
int x = positions[i][0] + direction[0];
int y = positions[i][1] + direction[1];
int neighborIndex = n * x + y;
if(x < 0 || x >= m || y < 0 || y >= n || id[neighborIndex] == -1) {
continue;
}
if(!connected(id, index, neighborIndex)) {
union(id, neighborIndex, index);
count--;
}
} res.add(count);
}
return res;
} private boolean connected(int[] id, int p, int q) {
return id[p] == id[q];
} private void union(int[] id, int p, int q) {
int pid = id[p];
int qid = id[q];
for(int i = 0; i < id.length; i++) {
if(id[i] == pid) {
id[i] = qid;
}
}
}
}

二刷:

加入了Path compression以及Weight, 速度快了不少。

Time Complexity - (k * logmn)  Space Complexity - O(mn),  这里k是positions的长度

public class Solution {
private int[] id;
private int[] sz;
private int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public List<Integer> numIslands2(int m, int n, int[][] positions) {
List<Integer> res = new ArrayList<>();
if (positions == null || positions.length == 0 || m < 0 || n < 0) {
return res;
}
id = new int[m * n];
sz = new int[m * n];
for (int i = 0; i < id.length; i++) {
id[i] = i;
} int count = 0;
for (int[] position : positions) {
int p = position[0] * n + position[1];
sz[p]++;
count++;
for (int[] direction : directions) {
int newRow = position[0] + direction[0];
int newCol = position[1] + direction[1];
if (newRow < 0 || newCol < 0 || newRow > m - 1 || newCol > n - 1) {
continue;
}
int q = newRow * n + newCol;
if (sz[q] > 0) {
if (isConnected(p, q)) {
continue;
} else {
union(p, q);
count--;
}
}
}
res.add(count);
}
return res;
} private int getRoot(int p) {
while (p != id[p]) {
id[p] = id[id[p]];
p = id[p];
}
return p;
} private boolean isConnected(int p, int q) {
return getRoot(p) == getRoot(q);
} private void union(int p, int q) {
int rootP = getRoot(p);
int rootQ = getRoot(q);
if (rootP == rootQ) {
return;
} else {
if (sz[p] < sz[q]) {
id[rootP] = rootQ;
sz[q] += sz[p];
} else {
id[rootQ] = rootP;
sz[p] += sz[q];
}
}
}
}

Reference:

https://leetcode.com/discuss/69392/python-clear-solution-unionfind-class-weighting-compression

https://www.cs.princeton.edu/~rs/AlgsDS07/01UnionFind.pdf

https://leetcode.com/discuss/69397/my-simple-union-find-solution

https://leetcode.com/discuss/69572/easiest-15ms-java-solution-written-mins-with-explanations

https://leetcode.com/discuss/69585/union-find-java-implements

https://leetcode.com/discuss/69374/solution-using-union-find-path-compression-weight-balancing

https://leetcode.com/discuss/70392/java-union-find-solution

https://leetcode.com/discuss/72435/share-my-java-union-find-solution

https://leetcode.com/discuss/69513/simple-python-not-normal-union-find

http://algs4.cs.princeton.edu/15uf/

305. Number of Islands II的更多相关文章

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

  2. LeetCode 305. Number of Islands II

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

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

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

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

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

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

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

  9. LintCode "Number of Islands II"

    A typical Union-Find one. I'm using a kinda Union-Find solution here. Some boiler-plate code - yeah ...

随机推荐

  1. 玩耍Hibernate之缓存

    2.在持久化层,对象分为哪些状态?分别列出来. 答:瞬时态(Transient).持久态(Persistent).脱管态(Detached). 瞬时态(Transient) 是对象是创建时,瞬时对象在 ...

  2. Eclipse中的常用快捷键

    快捷修复 Command+1 //int a=100L; //int a=(int) 100L; 快捷删除行 Command+D 快速起新行 Shift+Enter (当本行代码很长时,将光标定在本行 ...

  3. SQL通用查询

    获取日期截取 ), ) --不要时间2002-1-1 ),) ----20020101 ),) ---06:05:05

  4. SQLServer BCP 命令的使用

    现在有一个包含数据的文件,每个字段用“|”分隔,现在要把这些数据导入到数据库的表中. 数据文件如下: R001|20150710 可以使用如下命令: bcp testDB.dbo.testTable ...

  5. boost环境搭建

    切换到boost目录下面,使用编译命令>bjam.exe --with-date_time --toolset=msvc-9.0 --build-type=complete stage --wi ...

  6. 【BZOJ】【1044】【HAOI2008】木棍分割

    二分/DP 真是一道好题! 第一问很简单的二分…… 第二问一开始我想成贪心了,其实应该是DP的= = 然后没有注意……又MLE又TLE的……这题要对DP进行时空两方面的优化!! 题解:(by JoeF ...

  7. 【POJ】【3680】Intervals

    网络流/费用流 引用下题解: lyd: 首先把区间端点离散化,设原来的数值i离散化后的标号是c[i].这样离散化之后,整个数轴被分成了一段段小区间. 1.建立S和T,从S到离散化后的第一个点连容量K, ...

  8. Hdu 1507 Uncle Tom's Inherited Land* 分类: Brush Mode 2014-07-30 09:28 112人阅读 评论(0) 收藏

    Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  9. phonegap上传以及下载图片

    在phonegap中,有时我们需要从服务器下载图片以及上传图片,这个时候可以用到官方提供的一个插件:FileTransfer 首先通过命令添加插件: cordova plugin add org.ap ...

  10. HDU1056 HangOver

    HangOver Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Descript ...