题目:

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. layoutSubviews 浅尝

    layoutSubviews是UIView中的属性方法,即只要继承于UIView,就可以使用这个方法,这个方法也很强大,以下是他的触发时机: 1.init初始化不会触发layoutSubviews 2 ...

  2. 对C++中高内聚,低耦合原则的理解

    1.C语言是面向过程的语言,采用模块化的设计思想,每个功能划分为一个模块,是以函数为单位的. 2.C++是面向对象的语言,采用类设计的思想,因此C++中的模块是以类为基本单位的. 高内聚,低耦合能够使 ...

  3. 详解使用CSS3绘制矩形、圆角矩形、圆形、椭圆形、三角形、弧

    1.矩形 绘制矩形应该是最简单的了,直接设置div的宽和高,填充颜色,效果就出来了. 2.圆角矩形 绘制圆角矩形也很简单,在1的基础上,在使用css3的border-radius,即可. 3.圆 根据 ...

  4. 向Array中添加选择排序

    选择排序思路 在无序区中选出最小的元素,然后将它和有序区的第一个元素交换位置. 选择排序实现 Function.prototype.method = function(name, func){ thi ...

  5. asp.net 实现微信公众平台的主动推送信息

    通过学习借鉴朋友的实现方法进行整理(微信公众帐号主动发送消息给用户,asp.net版本). /// <summary> /// MD5 32位加密 /// </summary> ...

  6. JS中的间歇(周期)调用setInterval()与超时(延迟)调用setTimeout()相关总结

    超时调用需要使用window.setTimeout(code,millisec)方法 它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒).其中第一个参数可以是一个包含JS ...

  7. DB2 的create or update方法

    通过merge方法实现的: MERGE INTO IFEBASE.STYLE AS MT USING (SELECT :scenario AS SCENARIO_ID, :style AS SHAPE ...

  8. IE6下position解决父元素被撑开的问题

    在IE6下面当子元素的宽度/高度大于父元素时, 父元素的宽度/高度就被撑开.IE7以上是不会被撑开的 <style> .f{width:100px; height:100px; backg ...

  9. 使用行为树(Behavior Tree)实现网游奖励掉落系统

    原地址:http://blog.csdn.net/akara/article/details/6165421 [原创]使用行为树(Behavior Tree)实现网游奖励掉落系统by AKara 20 ...

  10. 在 Java EE 组件中使用 Camel Routes

    摘要:你可以通过集成 Camel 和 WildFly 应用服务器(使用 WildFly-Camel 子系统)在 Java EE 组件中开始使用 Apache Camel Routes. [编者按]作者 ...