778. 水位上升的泳池中游泳

一、题目描述

在一个 N x N 的坐标方格 grid 中,每一个方格的值 grid[i][j] 表示在位置 (i,j) 的平台高度。
现在开始下雨了。当时间为 t 时,此时雨水导致水池中任意位置的水位为 t 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。
你从坐标方格的左上平台 (0,0) 出发。最少耗时多久你才能到达坐标方格的右下平台 (N-1, N-1)?
示例 1:
输入: [[0,2],[1,3]]
输出: 3
解释:
时间为0时,你位于坐标方格的位置为 (0, 0)。
此时你不能游向任意方向,因为四个相邻方向平台的高度都大于当前时间为 0 时的水位。
等时间到达 3 时,你才可以游向平台 (1, 1). 因为此时的水位是 3,坐标方格中的平台没有比水位 3 更高的,所以你可以游向坐标方格中的任意位置
示例2:
输入: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
输出: 16
解释:
0 1 2 3 4
24 23 22 21 5
12 13 14 15 16
11 17 18 19 20
10 9 8 7 6
最终的路线用加粗进行了标记。
我们必须等到时间为 16,此时才能保证平台 (0, 0) 和 (4, 4) 是连通的

难度:困难
二、题解

class UnionFind{
    
    
    public:
        int n;
        int count;
        vector<int> parent;
        vector<int> size;
    public:
        UnionFind(int _n):n(_n),count(_n),size(_n,1),parent(_n){
    
    
            iota(parent.begin(), parent.end(), 0);
        }   
        int find(int x){
    
    
            return parent[x] == x ? x : parent[x] = find(parent[x]);
        }
        bool merge(int x,int y){
    
    
            x = find(x);
            y = find(y);
            if(x == y)
                return true;
            if(size[x]<=size[y])
                parent[x] = y;
            else
                parent[y] = x;
            if(size[x]==size[y])
                size[y]++;
            --count;
            return false;
        }
        bool isConnect(int x,int y){
    
    
            x = find(x);
            y = find(y);
            return x == y;
        }
};
class Solution {
    
    
private: 
    int N;
    int DIRECTIONS[4][2] = {
    
    {
    
    0, 1}, {
    
    0, -1}, {
    
    1, 0}, {
    
    -1, 0}};
public:
    int swimInWater(vector<vector<int>>& grid) {
    
    
        N = grid.size();
        int len = N * N;
        UnionFind uf(len);
        vector<int> index(len);
        for(int i=0;i<N;i++){
    
    
            for(int j =0;j<N;j++){
    
    
                index[grid[i][j]] = getIndex(i,j);//下标为平台高度,值为结点值
            }
        }
        for(int t=0;t<len;t++){
    
    //t为时间
            //时间t对应的结点位置
            int x = index[t] / N;
            int y = index[t] % N;

            //上下左右四个方向
            for(int k=0;k<4;k++){
    
    
                int newX = x + DIRECTIONS[k][0];
                int newY = y + DIRECTIONS[k][1];
                //r如果有小于等于当前时刻的坐标,则合并
                if(inArea(newX,newY)&&grid[newX][newY]<=t)
                    uf.merge(index[t],getIndex(newX,newY));
                
                if(uf.isConnect(0,len-1))
                    return t;
            }
        }
        return -1;
        
    }
    int getIndex(int x,int y){
    
    
        return x * N + y;
    }
    bool inArea(int x,int y){
    
    
        return x>=0&&x<N&&y>=0&&y<N;
    }
};








猜你喜欢

转载自blog.csdn.net/qq_38748148/article/details/113432444