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; } };
浙公网安备 33010602011771号