题目
https://leetcode-cn.com/problems/swim-in-rising-water/
分析
每经过一个时刻,就考虑此时和雨水高度相等的单元格,考虑这个单元格的上、下、左、右、四个方向,并且高度更低的单元格,把它们在并查集中进行合并。
代码
class Solution {
int[] index;
int[][] move={{-1,0},{1,0},{0,-1},{0,1}};
public int swimInWater(int[][] grid) {
int n=grid.length;
int len=n*n;
index=new int[len];//方格的编号=i*n+j
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
//高度为grid[i][j]的格子编号是i*n+j
index[grid[i][j]]=i*n+j;
}
}
UnionFind uf=new UnionFind(len);
for(int i=0;i<len;i++){
//index[i]:高度为i的格子编号,格子位置(x,y)
int x=index[i]/n;
int y=index[i]%n;
//上下左右
for(int[] next:move){
int nx=x+next[0];
int ny=y+next[1];
//没越界&被淹没
if(nx>=0&&nx<n&&ny>=0&&ny<n&&grid[nx][ny]<=i){
uf.union(index[i],nx*n+ny);
}
//到达右下角
if(uf.connect(0,n*n-1)){
return i;
}
}
}
return -1;
}
}
class UnionFind{
int[] parent;
public UnionFind(int n){
parent=new int[n];
for(int i=0;i<n;i++){
parent[i]=i;
}
}
public int find(int index){
if(parent[index]!=index){
parent[index]=find(parent[index]);
}
return parent[index];
}
public void union(int index1,int index2){
int p1=find(index1);
int p2=find(index2);
if(p1==p2)
return;
parent[p1]=p2;
}
public boolean connect(int index1,int index2){
int p1=find(index1);
int p2=find(index2);
if(p1==p2)
return true;
return false;
}
}