当前位置: 首页 > article >正文

Leetcode 778 Swim in a Rising water

题是指什么时候你能从左上角游到右下角。第t分钟的时候,水的高度是t。grid[i][j]是海拔,只有当前水的高度没过海拔,我才能游。你可以往四个方向游泳。求问,最少第几分钟我能从左上角游到右下角(有一条路径)
从本质上是要求找到一个最小的h,使得从左上角走到右下角能游完
解题思路:二分答案,h的范围肯定是grid[0][0],到grid中的最大值,取定一个h,看能不能游完

bfs求解

class Solution {
public:
    int swimInWater(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int l = 0, r = 0;
        for(int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                r = max(r, grid[i][j]);
            }
        }

        while (l < r) {
            int mid = l + (r - l) / 2;
            if(bfs(mid, grid)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }

    using PII = pair<int, int>;
    bool bfs(int h, vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        queue<PII> q;
        int dk[] = {-1, 0, 1, 0, -1};
        if(grid[0][0] > h) {
            return false;
        }
        q.push({0,0});
        vector<vector<int>> vis(m, vector<int>(n, 0));
        vis[0][0] = true;
        while(q.size()) {
            auto node = q.front();
            q.pop();
            int x = node.first;
            int y = node.second;
            if(x == m - 1 && y == n - 1) {
                return true;
            } 
            for(int i = 0; i < 4; i++) {
                int nx = x + dk[i];
                int ny = y + dk[i+1];
                if(nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny] && grid[nx][ny] <= h) {
                    vis[nx][ny] = true;
                    q.push({nx, ny});
                }
            }
        }
        return false;
    }

};

dfs求解

class Solution {
public:
    int swimInWater(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int l = 0, r = 0;
        for(int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                r = max(r, grid[i][j]);
            }
        }

        while (l < r) {
            int mid = l + (r - l) / 2;
            vector<vector<int>> vis(m, vector<int>(n, 0));
            if(dfs(0, 0, mid, vis, grid)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }

    bool dfs(int x, int y, int h, vector<vector<int>>& vis, vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        if(grid[x][y] > h) {
            return false;
        }
        if(x == m - 1 && y == n - 1) {
            return true;
        }
        vis[x][y] = 1;
        int dk[] = {-1, 0, 1, 0, -1};
        for(int i = 0; i < 4; i++) {
            int dx = x + dk[i];
            int dy = y + dk[i+1];
            if(dx >= 0 && dx < m && dy >= 0 && dy < n && !vis[dx][dy] && dfs(dx, dy, h, vis, grid)) {
                return true;
            } 
        }
        return false;
    }


};

算法复杂度O(mnlog(mn)), 空间复杂度O(mn)


http://www.kler.cn/a/386451.html

相关文章:

  • 【2024软考架构案例题】你知道 Es 的几种分词器吗?Standard、Simple、WhiteSpace、Keyword 四种分词器你知道吗?
  • 数字孪生在智慧能源项目中的关键作用,你了解多少?
  • TortoiseSVN提示服务器凭证检核错误:站点名称不符
  • 【算法】——二分查找合集
  • Flink_DataStreamAPI_输出算子Sink
  • 使用Matlab建立随机森林
  • (十三)JavaWeb后端开发——MySQL2
  • Spring的异步详解(@Async)
  • arkUI:层叠布局(Stack)
  • 测试概念以及测试bug
  • cannot locate symbol _ZTVNSt6__ndk119basic_ostringstreamIcNS_
  • 自动化细胞核分割与特征分析
  • 如何利用动态住宅IP高效抓取亚马逊数据并避开封禁
  • react的创建与书写
  • node.js安装配置(Windows)
  • 我应该如何使用这个API接口来展示商品信息呢
  • 【图像与点云融合教程(五)】海康相机 ROS2 多机分布式实时通信功能包
  • 美的品牌店铺运营全解析:洞察用户行为驱动增长
  • 【excel基本操作-sumif绝对引用和相对引用
  • 《Atomic Picnic》进不去游戏解决方法
  • 呼叫中心外呼主要用于哪些场景?
  • 【ARM Linux 系统稳定性分析入门及渐进 1.9.1 -- Crash 命令 System State 集合】
  • 关于99.9% 达成读码率方案
  • js 下载在线视频等多个文件到一个文件夹导出压缩包下载到本地
  • 棱镜七彩参加“融易行”产融对接南京站项目路演活动 展示供应链安全创新成果
  • 时序数据库之influxdb和倒排索引以及LSM-TREE