Number of Islands II
Description
Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y means that you can change the grid matrix[A[i].x][A[i].y] from sea to island. Return how many island are there in the matrix after each operator.
Example
Example 1:
Input: n = 4, m = 5, A = [[1,1],[0,1],[3,3],[3,4]]
Output: [1,1,2,2]
Explanation:
0. 00000
00000
00000
00000
1. 00000
01000
00000
00000
2. 01000
01000
00000
00000
3. 01000
01000
00000
00010
4. 01000
01000
00000
00011
Example 2:
Input: n = 3, m = 3, A = [[0,0],[0,1],[2,2],[2,1]]
Output: [1,1,2,2]
解题思路:
定义一个矩阵记录地图状态, 还需要定义初始含 n \times mn×m 个集合的并查集, 以及一个计数器, 记录当前岛屿的个数.
对于每一次操作(x, y), 如果(x, y)的上下左右都是0, 那么计数器加一; 如果不全为0, 则:
- 并查集查询其四周的1所属的集合, 假设它们属于 k 个不同的集合
- 计数器减去 k-1
- 将这 k 个集合, 连同 (x, y), 合并
并查集的实现可以利用Point结构体, 也可以将二维坐标转换成一维.
如果定义类,需重写类的Hashcode 方法和equals方法
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
/**
* @param n: An integer
* @param m: An integer
* @param operators: an array of point
* @return: an integer array
*/
class MyPoint{
int x;
int y;
MyPoint() { x = 0; y = 0; }
MyPoint(int a, int b) { x = a; y = b; }
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
return this.x == ((MyPoint) obj).x && this.y == ((MyPoint) obj).y;
}
@Override
public int hashCode() {
return x * 10 + y;
}
}
class UnionFind{
HashMap<MyPoint, MyPoint> father = new HashMap<>();
UnionFind(int n, int m) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
MyPoint p = new MyPoint(i, j);
father.put(p, p);
}
}
}
MyPoint find(MyPoint p) {
MyPoint point = p;
while (point != father.get(point)) {
point = father.get(point);
}
MyPoint root = point;
while (p != father.get(p)) {
MyPoint tmp = father.get(p);
father.put(tmp, root);
p = tmp;
}
return root;
}
void union(MyPoint p1, MyPoint p2) {
MyPoint root1 = find(p1);
MyPoint root2 = find(p2);
if (root1 != root2) {
father.put(father.get(root1), root2);
}
}
}
public List<Integer> numIslands2(int n, int m, Point[] operators) {
List<Integer> ans = new ArrayList<>();
if (operators == null || operators.length == 0) {
return ans;
}
int[] dx = {0, -1, 0, 1};
int[] dy = {1, 0, -1, 0};
int[][] island = new int[n][m];
UnionFind uf = new UnionFind(n, m);
int count = 0;
for (int i = 0; i < operators.length; i++) {
int x = operators[i].x;
int y = operators[i].y;
MyPoint p = new MyPoint(x, y);
if (island[x][y] != 1) {
island[x][y] = 1;
count++;
for (int j = 0; j < 4; j++) {
int nx = x + dx[j];
int ny = y + dy[j];
MyPoint np = new MyPoint(nx, ny);
if (0 <= nx && nx < n && 0 <= ny && ny < m && island[nx][ny] == 1) {
MyPoint root1 = uf.find(p);
MyPoint root2 = uf.find(np);
if (root1 != root2) {
count--;
uf.union(p, np);
}
}
}
}
ans.add(count);
}
return ans;
}
}

浙公网安备 33010602011771号