leetcode 1162. 地图分析 和 994. 腐烂的橘子

1162. 地图分析

题目:https://leetcode-cn.com/problems/as-far-from-land-as-possible/

你现在手里有一份大小为 n x n 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地。

请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,并返回该距离。如果网格上只有陆地或者海洋,请返回 -1。

我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。

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

 

方法一:采用回溯+深度搜索,将每一个山的定点,围着四周都搜索一遍。并且用辅助空间记录每个点的举例,搜索的时候,刷新距离。但是这种方法只能通过29个用例。后面用例超时,第三十个用例需要耗时2秒。

方法二:最短距离采用BFS,最后查询搜索的次数。

方法一(超时):

class Solution {
public:
    void maxDistance_dfs(int i, int j, int len, const vector<vector<int>>& grid, vector<vector<int>>& path, vector<vector<bool>>& visited)
    {
        if (i < 0 || j < 0 || i >= (int)grid.size() || j >= (int)grid[i].size() || visited[i][j] || (grid[i][j] == 1)) {
            return;
        }
        if (path[i][j] < len && path[i][j] != -1) {
            return;
        }
        path[i][j] = len;
        visited[i][j] = true;
        maxDistance_dfs(i + 1, j, len + 1, grid, path, visited);
        maxDistance_dfs(i - 1, j, len + 1, grid, path, visited);
        maxDistance_dfs(i, j + 1, len + 1, grid, path, visited);
        maxDistance_dfs(i, j - 1, len + 1, grid, path, visited);
        visited[i][j] = false;
    }

    // https://leetcode-cn.com/problems/as-far-from-land-as-possible/
    int maxDistance(vector<vector<int>>& grid)
    {
        vector<vector<bool>> visited(grid.size(),vector<bool>(grid[0].size(), false));
        vector<vector<int>> path(grid.size(),vector<int>(grid[0].size(), -1));
        for (int i = 0; i < (int)grid.size(); ++i) {
            for (int j = 0; j < (int)grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    maxDistance_dfs(i + 1, j, 1, grid, path, visited);
                    maxDistance_dfs(i - 1, j, 1, grid, path, visited);
                    maxDistance_dfs(i, j + 1, 1, grid, path, visited);
                    maxDistance_dfs(i, j - 1, 1, grid, path, visited);
                }
            }
        }
        int max = -1;
        for (int i = 0; i < (int)path.size(); ++i) {
            for (int j = 0; j < (int)path[i].size(); ++j) {
                max = max < path[i][j] ? path[i][j] : max;
            }
        }
        return max;
    }
};

 

方法二:

解题思路参考:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/lu-di-bu-duan-chang-da-zhi-dao-fu-gai-zheng-ge-di-/

class Solution {
public:
    int bfs_find(vector<vector<int>>& grid, queue<pair<int,int>>& pos)
    {
        int cnt = -1;
        while (pos.size() > 0) {
            int len = pos.size();
            ++cnt;
            while (len > 0) {
                // 统计遍历查找次数
                pair<int, int> top = pos.front();
                pos.pop();
                // 四个方向
                int dic[4][2] = {{0,  1},
                                 {0,  -1},
                                 {1,  0},
                                 {-1, 0}};
                // 遍历四个方向,走一步
                for (int i = 0; i < 4; ++i) {
                    int x = top.first + dic[i][0];
                    int y = top.second + dic[i][1];
                    if (x < 0 || y < 0 || x >= (int)grid.size() || y >= (int)grid[0].size() || grid[x][y] == 1) {
                        continue;
                    }
                    pos.push(pair<int,int>(x, y));
                    // 标记已走过
                    grid[x][y] = 1;
                }
                len--;
            }
        }
        return cnt > 0 ? cnt: -1;
    }

    // https://leetcode-cn.com/problems/as-far-from-land-as-possible/
    int maxDistance(vector<vector<int>>& grid) {
        queue<pair<int,int>> pos;
        for (int i = 0; i < (int)grid.size(); ++i) {
            for (int j = 0; j < (int)grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    pos.push(pair<int,int>(i,j));
                }
            }
        }
        return bfs_find(grid, pos);
    }
};

 

994. 腐烂的橘子

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

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

class Solution {
public:
    int GetBrokenMin(vector<vector<int>>& grid, queue<pair<int,int>>& pos)
    {
        int times = -1;
        while (!pos.empty()) {
            ++times;
            int len = pos.size();
            while (len > 0) {
                len--;
                pair<int, int> top = pos.front();
                pos.pop();
                int dir[4][2] = {{0,  1},
                                 {0,  -1},
                                 {1,  0},
                                 {-1, 0},};
                for (int i = 0; i < 4; ++i) {
                    int x = top.first + dir[i][0];
                    int y = top.second + dir[i][1];
                    if (x < 0 || y < 0 || x >= (int)grid.size() || y >= (int)grid[x].size() || grid[x][y] == 0 ||
                        grid[x][y] == 2) {
                        continue;
                    }
                    // 标记橘子已烂
                    grid[x][y] = 2;
                    pos.push(pair<int, int>(x, y));
                }
            }
        }
        return times;
    }

    // https://leetcode-cn.com/problems/rotting-oranges/
    int orangesRotting(vector<vector<int>>& grid) {
        bool someOrg = false;
        queue<pair<int, int>> pos;
        for (int i = 0; i < (int) grid.size(); ++i) {
            for (int j = 0; j < (int) grid[i].size(); ++j) {
                if (grid[i][j] == 2) {
                    pos.push(pair<int, int>(i, j));
                }
                if (grid[i][j] == 1) {
                    someOrg = true;
                }
            }
        }
        // 一开始就没有新鲜橘子
        if (!someOrg) {
            return 0;
        }
        // 一开始就没有坏橘子
        if (pos.empty()) {
            return -1;
        }
        int min = GetBrokenMin(grid, pos);
        // 再查找一遍,是否有好的橘子
        for (int i = 0; i < (int) grid.size(); ++i) {
            for (int j = 0; j < (int) grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    return -1;
                }
            }
        }
        return min;
    }
};

 

posted on 2022-04-09 11:00  蜀山菜鸟  阅读(33)  评论(0)    收藏  举报