特别要注意数据范围,gird数组是0到N*N-1的一个排列
思路有两种,第一种枚举时间(二分),从起点开始深搜或者BFS,看是否能到达右下角。
第一种的时间复杂度是
第二种思路是模拟时间,进行并查集操作,直到起点和终点连通起来。这个思路比较直接,解答选用这个思路
const int dx[] = {1,0,-1,0};
const int dy[] = {0,1,0,-1};
class Union{
private:
int n;
vector<int> p;
public:
Union(int n){
this->n = n;
p.resize(n);
for(int i=0;i<n;i++) p[i] = i;
}
int find(int x){
if(p[x]!=x) p[x] = find(p[x]);
return p[x];
}
void unite(int x, int y){
p[find(x)] = find(y);
}
bool isUnite(int x, int y){
return find(x)==find(y);
}
};
class Solution {
public:
int swimInWater(vector<vector<int>>& grid) {
int n = grid.size();
vector<int> hashmap(n*n);
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
hashmap[grid[i][j]] = i*n+j;
}
}
//for(auto val:hashmap) cout<<val<<" ";
Union un(n*n);
for(int i=0;i<n*n;i++){
int index = hashmap[i];
int x = index/n, y = index%n;
for(int j=0;j<4;j++){
int a = x + dx[j], b = y + dy[j];
if(a>=0&&a<n&&b>=0&&b<n&&grid[a][b]<=i){
un.unite(index,a*n+b);
}
}
if(un.isUnite(0,n*n-1)) return i;
}
return n*n-1;
}
};