题目:

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. 四则运算2扩展---c++

    题目:让程序能接受用户输入答案,并判定对错.最后给出总共对/错 的数量. 一.设计思想 1.存储用户输入答案,与正确答案比较得出总共对错数量. 二.源程序代码 #include<iostream ...

  2. CoffeeRobotTeam项目组报告

    一.小组分工 模块 任务 责任人 备注 报告 需求分析 熊振威 功能分析 熊振威 项目报告 熊振威 人机界面 秦勤.洪超 单元测试 姜进.张文强 机器人代码 机器人类 徐意.余拥军.孙智博 机器人运动 ...

  3. ELK:kibana使用的lucene查询语法

    kibana在ELK阵营中用来查询展示数据elasticsearch构建在Lucene之上,过滤器语法和Lucene相同 kibana4官方演示页面 全文搜索 在搜索栏输入login,会返回所有字段值 ...

  4. Java应用程序实现屏幕的"拍照"

    有时候,在Java应用程序开发中,如:远程监控或远程教学,常常需要对计算机的屏幕进行截取,由于屏幕截取是比较接近操作系统的操作,在Windows操作系统下,该操作几乎成了VC.VB等的专利,事实上,使 ...

  5. android开发 WriteUTF与readUTF 原理

    今晚上写代码玩,用到java.io.RandomAccessFile.writeUTF(String)函数,而文件默认保存为gbk,显然是乱码.突然想起来去看看存储编码规则,就去找了些文章了解writ ...

  6. UVALive - 6952 Cent Savings dp

    题目链接: http://acm.hust.edu.cn/vjudge/problem/116998 Cent Savings Time Limit: 3000MS 问题描述 To host a re ...

  7. 【转载】Oracle的方案(Schema)和用户(User)的区别

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:立正_敬礼_喊志哥     原文地址:http://my.oschina.ne ...

  8. [poj 1741]Tree 点分治

    题意 求树上距离不超过k的点对数,边权<=1000 题解     点分治.     点分治的思想就是取一个树的重心,这种路径只有两种情况,就是经过和不经过这个重心,如果不经过重心就把树剖开递归处 ...

  9. 女性社区TOP10

    “女性和孩子的钱是世界上最好赚的”并不是一句空话.据统计,女性掌管着家庭70%的支出,如果你能让女性为你掏出腰包,那么你基本就掌控了一个家庭的大部分的消费. 有趣的是,女性还是一个喜欢分享的群体,他们 ...

  10. MySQL 5.7 虚拟列 (virtual columns)

    参考资料: Generated Columns in MySQL 5.7.5 MySQL 5.7新特性之Generated Column(函数索引) MySQL 5.7原生JSON格式支持 Gener ...