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

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

在这里插入图片描述


C代码:二分查找 + BFS

// 题意:最开始下雨,水位必须淹没对应的两个位置,才能游过去!
// 相当于,就是找最大值!

const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

bool check(int** grid, int m, int n, int mid) {
    if (grid[0][0] > mid) {  // 相比[1631. 最小体力消耗路径] 多的部分
        return false;        // 下面校验的是四个方向的点,当前点也需要校验
    }
    int visited[m][n];
    memset(visited, 0, sizeof(int) * m * n);
    visited[0][0] = 1;

    int que[m * n][2];
    memset(que, 0, sizeof(int) * m * n * 2);
    int qhead = 0;
    int qtail = 0;
    que[qtail][0] = 0;
    que[qtail++][1] = 0;

    while (qhead < qtail) {
        int x = que[qhead][0];
        int y = que[qhead++][1];
        for (int i = 0; i < 4; ++i) {  // BFS
            int dx = x + dir[i][0];
            int dy = y + dir[i][1];
            if (dx >= 0 && dx < m && dy >= 0 && dy < n && visited[dx][dy] != 1 && grid[dx][dy] <= mid) {
                visited[dx][dy] = 1;
                que[qtail][0] = dx;
                que[qtail++][1] = dy;
            }
        }
    }
    return visited[m - 1][n - 1] == 1;
}

int swimInWater(int** grid, int gridSize, int* gridColSize){
    int m = gridSize, n = gridColSize[0];
    int left = 0, right = m * m - 1;
    int ans = 0;
    while (left <= right) {  // 左闭右闭
        int mid = (left + right) / 2;
        if (check(grid, m, n, mid)) {  // mid这个高度能进行到最后,还需要减小;
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return ans;
}

java:DFS + 二分

public class Solution {
    private int N;
    public static final int[][] DIRECTIONS = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    public int swimInWater(int[][] grid) {
        this.N = grid.length;

        int left = 0;
        int right = N * N - 1;
        while (left < right) {  // 左闭右开
            int mid = (left + right) / 2;  // left + right 不会溢出 l + ((r-l) >> 1)
            boolean[][] visited = new boolean[N][N];
            if (grid[0][0] <= mid && dfs(grid, 0, 0, visited, mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

    private boolean dfs(int[][] grid, int x, int y, boolean[][] visited, int threshold) {
        visited[x][y] = true;
        for (int[] direction : DIRECTIONS) {
            int newX = x + direction[0];
            int newY = y + direction[1];
            if (inArea(newX, newY) && !visited[newX][newY] && grid[newX][newY] <= threshold) {
                if (newX == N - 1 && newY == N - 1) {
                    return true;
                }
                if (dfs(grid, newX, newY, visited, threshold)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean inArea(int x, int y) {
        return x >= 0 && x < N && y >= 0 && y < N;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值