题目:

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. Windows Phone 8内存控制研究 之 LonglistSelector使用陷阱

    最近工作中常常被问到如何降低WP内存使用,便再一次开始研究内存问题,首先发现了LonglistSelector使用的一个常见问题: 概述 若将Longlistselector 控件的ItemsSour ...

  2. Linux 前台 和 后台进程 说明

    一. 有关进程的几种常用方法 1.1  & 符号 在命令后面加上一个 & 符号,表示该命令放在后台执行,如: [oracle@singledb ~]$ crontab -l 20 17 ...

  3. 《实时控制软件设计》Git 基本操作练习

    根据老师提供的教程 对 数据库创建.提交文件.创建分支.删除分支.合并分支.冲突处理等操作进行了练习 得到log文件如下: yanbin-guo@yanbinguo MINGW64 /Git (mas ...

  4. 如何教你在NIPS会议上批量下载历年的pdf文档(另附04~14年NIPS论文下载链接)

    如何获得NIPS会议上批量下载的链接? NIPS会议下载网址:http://papers.nips.cc/ a.点击打开上述网站,进入某一年的所有会议,例如2014年,如下图 b.然后对着当前网页点击 ...

  5. javascript与DOM -- 深入理解javascript

    /* 一.文档对象模型Document Object Model DOM(Document Object Model,文档对象模型)是一个通过和JavaScript进行内容交互的API */ /* 注 ...

  6. JavaScript 异常

    转载自:http://www.cnblogs.com/aqbyygyyga/archive/2011/10/29/2228824.html(排版格式修改了一下) 一.错误处理的重要性 以前,javas ...

  7. 【转】免装版tomcat注册成windows系统服务方法

    转自:http://blog.csdn.net/huiwenjie168/article/details/42267353 一.下载Tomcat Tomcat可以从http://tomcat.apac ...

  8. Jquery方法的应用

    <body> <div id="one"><span>one</span></div><div class=&qu ...

  9. Nginx的accept_mutex配置分析

    让我们看看accept_mutex的意义:当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠 ...

  10. LUCAS 定理

    原来一张图就就能证明:C(N,M)%P,p是素数. 简直太炫酷 先膜拜会 #include<iostream>#include<cstdio>#include<ctime ...