zoukankan      html  css  js  c++  java
  • 778. 水位上升的泳池中游泳 (JAVA)

    在一个 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) 是连通的
     

    提示:

    2 <= N <= 50.
    grid[i][j] 是 [0, ..., N*N - 1] 的排列。

    思路:

    并查集问题(在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中),解决方法是二分法(看到有最大取值N*N - 1,想到用二分法)+BFS。

    定义 left、right 分别指向0和N*N - 1, 先取中间值mid;(这个序列表示的是t的取值范围)
    从左上角开始出发,向四个方向进行遍历访问(本题解用 BFS 方法+访问标记):
    如果此时能够找到一条路径,从左上角到达右下角,那么t落在[left, mid]处,可继续查找是否存在更小的时刻 ;
    如果未能找到一条路径时,那么要找的 一定比此时的t值大,落在[mid+1, right]中,往这个区间继续搜索。
    结束条件是访问到了grid[N-1][N-1]且<t,那么返回true。

    class Solution {
        public int swimInWater(int[][] grid) {
            int N = grid.length;
            int left = Math.max(grid[0][0], grid[N-1][N-1]);
            int right = N*N - 1;
            BitSet bs = new BitSet(right);
            int mid;
            while(left < right) {
                mid = (left + right) >> 1;
                if(dfs(grid, 0, 0, mid, bs)) right = mid;
                else left = mid+1;
                bs.clear();
            }
            return left;
        }
    
        private boolean dfs(int[][]grid, int i, int j, int threshold, BitSet bs){
            if(bs.get(i*grid.length+j) || grid[i][j] > threshold) return false;
            if(i == grid.length-1 && j == grid.length-1) return true;
            bs.set(i*grid.length + j);
            if(i > 0 && dfs(grid, i-1, j, threshold, bs)) return true;
            if(j > 0 && dfs(grid, i, j-1, threshold, bs)) return true;
            if(i < grid.length-1 && dfs(grid, i+1, j, threshold, bs)) return true;
            if(j < grid.length-1 && dfs(grid, i, j+1, threshold, bs)) return true;
            return false;
        }
    }
  • 相关阅读:
    volatile关键字,使一个变量在多个线程间可见。
    grep sed awk
    mysql高级聚合
    Hive高级聚合GROUPING SETS,ROLLUP以及CUBE
    用SecureCRT来上传和下载文件
    mysql导出导入数据
    redis入门
    spark 常用技巧总结2
    生成数据库字典
    spark 常用技巧总结
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/14472109.html
Copyright © 2011-2022 走看看