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]
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.
public class Solution {
private int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
private int numCC = 0;
public List<Integer> numIslands2(int n, int m, Point[] operators) {
List<Integer> ans = new ArrayList<>();
if (operators == null || operators.length == 0) {
return ans;
}
int[] parents = new int[n * m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
parents[i * m + j] = i * m + j;
}
}
Set<Integer> islands = new HashSet<>();
for (Point point : operators) {
if (!islands.contains(point.x * m + point.y)) {
islands.add(point.x * m + point.y);
numCC++;
for (int i = 0; i < 4; i++) {
connect(point.x, point.y, point.x + dirs[i][0], point.y + dirs[i][1], n, m, islands, parents);
}
}
ans.add(numCC);
}
return ans;
}
private void connect(int ax, int ay, int bx, int by, int n, int m, Set<Integer>islands, int[] parents) {
if (bx < 0 || bx >= n || by < 0 || by >= m) {
return;
}
if (!islands.contains(bx * m + by)) {
return;
}
int rootA = find(ax, ay, n, m, parents);
int rootB = find(bx, by, n, m, parents);
if (rootA != rootB) {
parents[rootB] = rootA;
numCC--;
}
}
private int find(int x, int y, int n, int m, int[] parents) {
int p = x * m + y;
int root = p;
while (root != parents[root]) {
root = parents[root];
}
// path compression
//
while (root != p) {
int temp = parents[p];
parents[p] = root;
p = temp;
}
return root;
}
}
/**
* 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
*/
private int[] parents;
private int numIslands = 0;
private int find(int x) {
int root = x;
while (parents[root] != root) {
root = parents[root];
}
// path compression
while (root != x) {
int temp = parents[x];
parents[x] = root;
x = temp;
}
return x;
}
private void union(int x, int y) {
int parentX = find(x);
int parentY = find(y);
if (parents[parentX] != parentY) {
parents[parentX] = parentY;
numIslands--;
}
}
public List<Integer> numIslands2(int n, int m, Point[] operators) {
// write your code here
List<Integer> ans = new ArrayList<>();
if (n <= 0 || m <= 0 || operators == null || operators.length == 0) {
return ans;
}
parents = new int[n * m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
parents[i * m + j] = i * m + j;
}
}
int[][] islands = new int[n][m];
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (Point opeartor : operators) {
int x = opeartor.x;
int y = opeartor.y;
if (islands[x][y] == 1) {
ans.add(numIslands);
continue;
}
numIslands += 1;
islands[x][y] = 1;
for (int[] dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && islands[nx][ny] == 1) {
union(x * m + y, nx * m + ny);
}
}
ans.add(numIslands);
}
return ans;
}
}
No comments:
Post a Comment