zoukankan      html  css  js  c++  java
  • [LeetCode每日1题][中等] 1162. 地图分析

    题目

    1162. 地图分析 - 力扣(LeetCode)
    在这里插入图片描述

    DFS解法

    class Solution
    {
        int N;
        vector<vector<int>> dist; // 存放结点到陆地的最短距离
        vector<vector<int>> *grid;
    
    public:
        int maxDistance(vector<vector<int>> &grid)
        {
            this->grid = &grid;
            N = grid.size();
            dist = vector<vector<int>>(N, vector<int>(N, -1)); // 初始化一个二维vector
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (grid[i][j])
                    {
                        dfs(i, j, 0); // 找到第一个陆地,开始dfs
                        break;
                    }
                }
            }
            int max_dist = INT_MIN;
            for (auto i : dist)
            {
                for (auto j : i)
                {
                    if (max_dist < j)
                        max_dist = j; // 找最大值
                }
            }
            return max_dist ? max_dist : -1;
        }
        void dfs(int i, int j, int step)
        {
            if ((*grid)[i][j])
            {
                step = 0; // 遇到陆地,重置step = 0, 接下来可能会出现回溯
            }
            if (dist[i][j] > step || dist[i][j] == -1) // 如果当前走法比历史走法更优
            {
                dist[i][j] = step++; // 更新为当前走法
                if (i > 0)
                    dfs(i - 1, j, step); // 往上走
                if (j > 0)
                    dfs(i, j - 1, step); // 往左走
                if (i < N - 1)
                    dfs(i + 1, j, step); // 往下走
                if (j < N - 1)
                    dfs(i, j + 1, step); // 往右走
            }
        }
    };
    

    多源BFS解法

    class Solution
    {
        struct Point
        {
            int x;
            int y;
        };
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
        queue<Point> q;
        const static int N = 101;
        int dist[N][N];
        int INF = 1E6;
    
    public:
        int maxDistance(vector<vector<int>> &grid)
        {
            int size = grid.size();
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (grid[i][j])
                    {
    	                // 所有陆地作为一个超级源点
                        q.push({i, j});
                        dist[i][j] = 0;
                    }
                    else
                    {
                        dist[i][j] = INF;
                    }
                }
            }
            while (!q.empty())
            {
                auto p = q.front();
                q.pop();
                for (int i = 0; i < 4; i++)
                {
                    int nx = p.x + dx[i], ny = p.y + dy[i];
                    if (nx >= 0 && nx < size && ny >= 0 && ny < size)
                    {
                        if (dist[nx][ny] > dist[p.x][p.y] + 1)
                        {
                            dist[nx][ny] = dist[p.x][p.y] + 1;
                            q.push({nx, ny}); // 节点被更新,可能影响周围结点,入队
                        }
                    }
                }
            }
            int _max = -1;
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (!grid[i][j])
                    {
                        _max = max(_max, dist[i][j]);
                    }
                }
            }
            return _max == INF ? -1 : _max;
        }
    };
    

    DP法

    class Solution {
    public:
        static constexpr int MAX_N = 100 + 5;
        static constexpr int INF = int(1E6);
        
        int f[MAX_N][MAX_N];
        int n;
    
        int maxDistance(vector<vector<int>>& grid) {
            this->n = grid.size();
            vector<vector<int>>& a = grid;
    
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    f[i][j] = (a[i][j] ? 0 : INF);
                }
            }
    
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (a[i][j]) continue;
                   	// 考虑更新值来自左或者上的情况,先dp一次
                    if (i - 1 >= 0) f[i][j] = min(f[i][j], f[i - 1][j] + 1);
                    if (j - 1 >= 0) f[i][j] = min(f[i][j], f[i][j - 1] + 1);
                }
            }
    
            for (int i = n - 1; i >= 0; --i) {
                for (int j = n - 1; j >= 0; --j) {
                    if (a[i][j]) continue;
                    // 在上个for循环的基础上,考虑更新值来自右或者下的情况,再dp一次
                    if (i + 1 < n) f[i][j] = min(f[i][j], f[i + 1][j] + 1);
                    if (j + 1 < n) f[i][j] = min(f[i][j], f[i][j + 1] + 1);
                }
            }
    
            int ans = -1;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (!a[i][j]) {
                        ans = max(ans, f[i][j]);
                    }
                }
            }
    
            if (ans == INF) return -1;
            else return ans;
        }
    };
    
    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/di-tu-fen-xi-by-leetcode-solution/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    参考

    地图分析 - 地图分析 - 力扣(LeetCode)

  • 相关阅读:
    hdu 2082 找单词
    hdu 2079 选课时间(题目已修改,注意读题)
    hdu 2073 无限的路
    hdu 2062 Subset sequence
    poj 2777 Count Color
    hdu 2067 小兔的棋盘
    卡特兰数
    poj3468
    hdu1394
    hdu1166(线段树之单点更新)
  • 原文地址:https://www.cnblogs.com/zaynq/p/12679070.html
Copyright © 2011-2022 走看看