Number of Islands II
Posted flagyuri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Number of Islands II相关的知识,希望对你有一定的参考价值。
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.
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
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]
思路使用并查集,并查集的实现可以利用Point结构体, 也可以将二维坐标转换成一维。注意使用类的时候需重写equals方法和hashCode方法。
对于每一次操作(x, y), 如果(x, y)的上下左右都是0, 那么计数器加一; 如果不全为0, 则:
- 并查集查询其四周的1所属的集合, 假设它们属于 k 个不同的集合
- 计数器减去 k-1
- 将这 k 个集合, 连同 (x, y), 合并
/** * 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 < m; 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(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; if (island[x][y] != 1) { island[x][y] = 1; count++; MyPoint p = new MyPoint(x, y); for (int j = 0; j < 4; j++) { int nx = x + dx[j]; int ny = y + dy[j]; if (0 <= nx && nx < n && 0 <= ny && ny < m && island[nx][ny] == 1) { MyPoint np = new MyPoint(nx, ny); MyPoint root1 = uf.find(p); MyPoint root2 = uf.find(np); if (root1 != root2) { count--; uf.union(p, np); } } } } ans.add(count); } return ans; } }
以上是关于Number of Islands II的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode 305. Number of Islands II