class Solution {
int m;
int n;
public int numEnclaves(int[][] grid) {
m = grid.length;
n = grid[0].length;
int size = m * n;
int sum = 0;
UnionFind uf = new UnionFind(size+1);
for(int i = 0;i < n;i++){
if(grid[0][i] == 1){
uf.union(size,i);
}
}
for(int i = 0;i < n;i++){
if(grid[m-1][i] == 1){
uf.union(size,getIndex(m-1,i));
}
}
for(int i = 0;i < m;i++){
if(grid[i][0] == 1){
uf.union(size,getIndex(i,0));
}
}
for(int i = 0;i < m;i++){
if(grid[i][n-1] == 1){
uf.union(size,getIndex(i,n-1));
}
}
for(int i =0;i < m;i++){
for(int j=0;j<n;j++){
if(grid[i][j] == 1){
sum += 1;
if(inArea(i-1,j)== true && grid[i-1][j] == 1){
uf.union(getIndex(i,j),getIndex(i-1,j));
}
if(inArea(i,j-1)== true && grid[i][j-1] == 1){
uf.union(getIndex(i,j),getIndex(i,j-1));
}
}
}
}
int root = uf.find(size);
return sum - (uf.size[root] - 1);
}
public boolean inArea(int x,int y){
return x >= 0 && x<m && y>=0 && y<n;
}
public int getIndex(int x,int y){
return x * n + y;
}
public class UnionFind{
int[] parent;
int[] rank;
int[] size;
public UnionFind(int n){
parent = new int[n];
rank = new int[n];
size = new int[n];
for(int i = 0;i < n;i++){
parent[i] = i;
rank[i] = 1;
size[i] = 1;
}
}
public int find(int x){
if(parent[x] != x){
parent[x] = find(parent[x]);
}
return parent[x];
}
public boolean isConnect(int x,int y){
int rootX = find(x);
int rootY = find(y);
if(rootX == rootY)
return true;
else
return false;
}
public void union(int x,int y){
int rootX = find(x);
int rootY = find(y);
if(rootX == rootY)
return ;
if(rank[rootX] == rank[rootY]){
parent[rootX] = rootY;
rank[rootY] += 1;
size[rootY] += size[rootX];
}
else if(rank[rootX] > rank[rootY]){
parent[rootY] = rootX;
size[rootX] += size[rootY];
}
else{
parent[rootX] = rootY;
size[rootY] += size[rootX];
}
}
}
}