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. 第一周:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

    姓名:吕松鸿 学号:20135229 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  2. Java入门第二季第2章封装

    什么是 Java 中的内部类 问:什么是内部类呢? 答:内部类( Inner Class )就是定义在另外一个类里面的类.与之对应,包含内部类的类被称为外部类. 问:那为什么要将一个类定义在另一个类里 ...

  3. 『编程题全队』Alpha 阶段冲刺博客Day5

    1.每日站立式会议 1.会议照片 2.昨天已完成的工作统计 孙志威: 1.完成SlotWidget的设计和功能 2.修改了TitleBar上的功能按钮的CSS样式表 孙慧君: 1.登录框的UI设计 2 ...

  4. Alpha冲刺——day8

    Alpha冲刺--day8 作业链接 Alpha冲刺随笔集 github地址 团队成员 031602636 许舒玲(队长) 031602237 吴杰婷 031602220 雷博浩 031602634 ...

  5. hao360恶意篡改IE首页——修复方法

    设置浏览器首页空白或自定义后,点击开始菜单,找到IE浏览器,右键进入属性,找到shortcut里面“目标”,你会看到里面链接到的是hao360什么乱糟糟的,这才是以上问题的关键原因.删除图1中红色内容 ...

  6. [转帖] Linux 下面栈空间大小的实验

    比如局部变量是保存在栈空间中的,今天突然在想栈的上限是多大呢,什么时候才会栈溢出? ulimit 命令 linux下使用ulimit 命令可以查看系统的很多上限值. ulimit -a 查看所有 ul ...

  7. day5——Java 实现导出excel表 POI(转)

    1.首先下载poi-3.6-20091214.jar,下载地址如下: http://download.csdn.net/detail/evangel_z/3895051 2.Student.java ...

  8. 消息队列1:RabbitMQ解析并基于Springboot实战

    RabbitMQ简介 AMQP:Advanced Message Queue,高级消息队列协议.它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产 ...

  9. CF1073E Segment Sum

    数位DP,求[L,R]区间内所有"数字内包含的不同数码不超过k个的数字"之和.在状态上加一维状态压缩表示含有的数码集合.一开始读错题以为是求数字的个数.读对题之后调了一会儿. #i ...

  10. BZOJ4066 简单题(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...