LeetCode 778. 水位上升的泳池中游泳(二分查找+dfs)

文章目录

    • 1. 题目
    • 2. 解题

1. 题目

在一个 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

最终的路线用加粗进行了标记。
我们必须等到时间为 16,此时才能保证平台 (0, 0)(4, 4) 是连通的

LeetCode 778. 水位上升的泳池中游泳(二分查找+dfs)_第1张图片

提示:
2 <= N <= 50.
grid[i][j] 位于区间 [0, ..., N*N - 1] 内。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/swim-in-rising-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

类似题目:LeetCode 1102. 得分最高的路径(优先队列BFS/极大极小化 二分查找)

跟上面题目一样,这题是找到 路径最大值 最小的路径,只需要在二分查找的地方做点修改

class Solution {
     
	vector<vector<int>> dir = {
      {
     1,0},{
     0,1},{
     0,-1},{
     -1,0}};
	int N;
public:
    int swimInWater(vector<vector<int>>& grid) {
     
        int l = grid[0][0], r = 2500, mid, ans;
        N = grid.size();
        while(l <= r)
        {
     
        	mid = (l + r) / 2;
        	vector<vector<bool>> vis(N, vector<bool>(N,false));
        	if(dfs(grid,0,0, mid, vis))
        	{
     	//可以找到一条路径,其上的值都 <= mid
        		ans = mid;
        		r = mid-1;
        	}
        	else
        		l = mid+1;
        }
        return ans;
    }
    bool dfs(vector<vector<int>>& grid, int x, int y, int MAX, vector<vector<bool>>& vis)
    {
     
    	vis[x][y] = true;
    	int i, j, k;
    	if(x == N-1 && y == N-1)
    	{
     
    		return true;
    	}
    	for(k = 0; k < 4; k++)
    	{
     
    		i = x + dir[k][0];
    		j = y + dir[k][1];
    		if(i >=0 && i < N && j >=0 && j < N && !vis[i][j] && grid[i][j] <= MAX)
    		{
     
    			if(dfs(grid, i, j, MAX, vis))
    				return true;
    		}
    	}
    	return false;
    }
};

36 ms 9.7 MB

优先队列也可以

struct point
{
     
	int x;
	int y;
	int val;
	point(int x0, int y0, int v)
	{
     
		x = x0;
		y = y0;
		val = v;
	}
};
struct cmp
{
     
    bool operator()(point& a, point& b) 
    {
     
        return a.val > b.val;//值小的优先
    }
};
class Solution {
     
    vector<vector<int>> dir = {
     {
     1,0},{
     0,1},{
     0,-1},{
     -1,0}};
public:
    int swimInWater(vector<vector<int>>& A) {
     
        int m = A.size(), n = A[0].size(), i, j, x, y, k, ans = A[0][0];
        vector<vector<bool>> visited(m, vector<bool>(n,false));
        visited[0][0] = true;
        priority_queue<point,vector<point>,cmp> q;
        q.push(point(0, 0, A[0][0]));
        while(!q.empty())
        {
     
            if(q.top().val > ans)
        	    ans = q.top().val;
        	i = q.top().x;
        	j = q.top().y;
        	q.pop();
        	if(i==m-1 && j==n-1)
        		return ans;
        	for(k = 0; k < 4; ++k)
        	{
     
        		x = i + dir[k][0];
        		y = j + dir[k][1];
        		if(x>=0 && x<m && y>=0 && y<n && !visited[x][y])
        		{
     
        			q.push(point(x, y, A[x][y]));
        			visited[x][y] = true;
        		}
        	}
        }
        return ans;
    }
};

52 ms 8.5 MB


我的CSDN博客地址 https://michael.blog.csdn.net/

长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!
Michael阿明

你可能感兴趣的:(LeetCode)