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

https://leetcode.cn/problems/swim-in-rising-water/

Dijkstra

class Solution {
public:
    int swimInWater(vector<vector<int>>& grid) {
        vector<int> dirs{1,0,-1,0,1};
        int m =grid.size(), n = grid[0].size();
        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;
        int dis[m][n];
        memset(dis, 0x3f, sizeof(dis));
     //   dis[0][0] = 0;
        pq.push({grid[0][0], 0, 0});

        //答案一定存在
        while (1) {
            auto [d, x, y] = pq.top(); pq.pop();
            // 到达终点
            if (x == m - 1 && y == n - 1) return d;
            // 四个方向寻找
            for (int i = 0; i<4; i++) {
                int a = x + dirs[i], b = y + dirs[i+1];
                if (a >= 0 && a < m && b >= 0 && b < n) {
                    int nd = max(d, grid[a][b]);
                    // 更新最短路
                    if (nd < dis[a][b]) {
                        dis[a][b] = nd;
                        pq.push({nd, a, b});
                    }
                }
            }
        }
    }
};
class Solution {
public:
    const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int swimInWater(vector<vector<int>>& grid) {
        int n = grid.size();
        // 记录是否访问过
        vector<vector<int>> seen(n, vector<int>(n, false)); 
        // 格式: [值,坐标]
        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<> > pq;

        pq.push({grid[0][0], 0, 0});
        while (!pq.empty()) {
            auto [val, x, y] = pq.top();pq.pop();

            // 去重
            if (seen[x][y]) continue;

            seen[x][y] = true;

            // 判断到达终点            
            if (x == n - 1 && y == n-1) return val;

            // 访问相邻
            for (int i = 0; i < 4; i++) {
                int nx = x + dir[i][0], ny = y + dir[i][1];
                if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
                pq.push({max(val, grid[nx][ny]), nx, ny});
            }
        }
        return 0;
    }
};

Binary Search + BFS

#define x first
#define y second
typedef pair<int, int> PII;

class Solution {
public:
    bool vis[51][51];
    int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
    int h, w;

    bool bfs(int xx, vector<vector<int>> & grid){
        memset(vis, 0, sizeof vis);
        queue<PII> q;
        vis[0][0] = true;
        q.push({0, 0});
        while(q.size()){
            auto t = q.front();
            q.pop();
            for(int i = 0; i < 4; i ++){
                int a = t.x + dx[i], b = t.y + dy[i];
                if(a >= 0 && a < h && b >= 0 && b < w  && !vis[a][b] && grid[a][b] <= xx){
                    if(a == grid.size()-1 && b == grid[1].size()-1) return true;
                    q.push({a, b});
                    vis[a][b] = true;
                }
            }
        }
        return false;
    }

    int swimInWater(vector<vector<int>>& grid) {
        h = grid.size();
        w = grid[0].size();

        if(h==1 && w==1) return 0; // 此处为能用dfs不要用bfs的原因 需要特殊处理 tx

        int l = 0;
        int r = h*w;
        while(l < r){//二分
            int mid = (l + r) >> 1;
            if(grid[0][0] <= mid && bfs(mid, grid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};

Binary Search + DFS

class Solution {
    const int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    bool vis[50][50];
    int n, m;
public:
    int swimInWater(vector<vector<int>>& heights) {
        m = heights.size();
        n = heights[0].size();
        int l = 0, r = n*n, m;
        while(l < r){
            m = (l + r) / 2;
            memset(vis[0], 0, sizeof(vis));
            if(heights[0][0] <= m && dfs(heights, 0, 0, m)){
                r = m;
            }
            else{
                l = m + 1;
            }
        }
        return l;
    }
    int dfs(vector<vector<int> >& heights, int i, int j, int limit){
        if(i==m-1&&j==n-1)return 1; // 通了
        vis[i][j] = 1;
        for(int t = 0; t < 4; t++){
            int ii = i + dirs[t][0];
            int jj = j + dirs[t][1];
            if(ii<0||ii>=m||jj<0||jj>=n 
                || vis[ii][jj] || heights[ii][jj] > limit) continue; // 限制边界/高
            if(dfs(heights, ii, jj, limit))return 1;
        }
        return 0; // 没通
    }

};

Union-Find

class Solution {
public:
    const int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    vector<int> F;
    int find(int x) {
        return x == F[x] ? F[x] : F[x] = find(F[x]);
    }
    int swimInWater(vector<vector<int>>& grid) {
        int N = grid.size();
        F.resize(N * N);
        iota(F.begin(), F.end(), 0);

        using tiii = tuple<int, int, int>; // time x y
        priority_queue<tiii, vector<tiii>, greater<> > nodes;

        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                nodes.push({grid[i][j], i, j});
            }
        }

        int t = 0;
        while (1) {
            auto [d, x, y] = nodes.top(); nodes.pop();
            int z = x * N + y;
            for (int i = 0; i < 4; ++i) {
                int nx = x + dirs[i][0];
                int ny = y + dirs[i][1];
                int curParent = find(z); 
                //grid[nx][ny]< t // 把当前node周围比自己小的元素吃掉,用当前元素的parent
                if (nx >= 0 && nx < N && ny >= 0 && ny < N && grid[nx][ny]< t) {
                    int nz = nx * N + ny;
                    F[find(nz)] = curParent ;
                }
            }

            if (find(0) == find(N * N - 1)) {
                return t;
            }
            
            t++;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值