317:离建筑物最近的距离

This commit is contained in:
轩辕龙儿 2022-03-22 21:12:48 +08:00
parent ab24f15ab5
commit b06f95d7a8
2 changed files with 203 additions and 0 deletions

View File

@ -0,0 +1,147 @@
//给你一个 m × n 的网格值为 0 1 2 其中:
//
//
// 每一个 0 代表一块你可以自由通过的 空地
// 每一个 1 代表一个你不能通过的 建筑
// 每个 2 标记一个你不能通过的 障碍
//
//
// 你想要在一块空地上建造一所房子 最短的总旅行距离 内到达所有的建筑你只能上下左右移动
//
// 返回到该房子的 最短旅行距离 如果根据上述规则无法建造这样的房子则返回 -1
//
// 总旅行距离 是朋友们家到聚会地点的距离之和
//
// 使用 曼哈顿距离 计算距离其中距离 (p1, p2) = |p2.x - p1.x | + | p2.y - p1.y |
//
//
//
// 示例 1
//
//
//
//
//输入grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
//输出7
//解析给定三个建筑物 (0,0)(0,4) (2,2) 以及一个位于 (0,2) 的障碍物
//由于总距离之和 3+3+1=7 最优所以位置 (1,2) 是符合要求的最优地点
//故返回7
//
//
// 示例 2:
//
//
//输入: grid = [[1,0]]
//输出: 1
//
//
// 示例 3:
//
//
//输入: grid = [[1]]
//输出: -1
//
//
//
//
// 提示:
//
//
// m == grid.length
// n == grid[i].length
// 1 <= m, n <= 50
// grid[i][j] 0, 1 2
// grid 至少 一幢 建筑
//
// Related Topics 广度优先搜索 数组 矩阵 👍 118 👎 0
package leetcode.editor.cn;
import javafx.util.Pair;
import java.util.LinkedList;
import java.util.Queue;
//317:离建筑物最近的距离
public class ShortestDistanceFromAllBuildings {
public static void main(String[] args) {
Solution solution = new ShortestDistanceFromAllBuildings().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
private int rows;
private int cols;
public int shortestDistance(int[][] grid) {
if (null == grid || grid.length == 0) {
return -1;
}
// 题目要找的是最合适的空地我们可以转换为假如某空地A(x,y)所有建筑物到A(x,y)的最短距离的总和
// 单个最短距离可以采用BFS算法
// 再在所有的空地最短距离中取最小距离
rows = grid.length;
cols = grid[0].length;
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
//记录每一个建筑到空地的距离每运算一次建筑到某空地的距离该空地就累加一次距离和
int[][] dist = new int[rows][cols];
int tallCount = 0;
int[][] countCalc = new int[rows][cols];
// distance[i][j]记录所有建筑物queue到某空地的最短距离
int ans = Integer.MAX_VALUE;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
ans = bfs(grid, new int[]{i, j, 0}, countCalc, dist, tallCount);
tallCount++;
//ans = Math.min(ans,temp);
}
}
}
return ans == Integer.MAX_VALUE ? -1 : ans;
}
// 计算每一个建筑tallPair到空地(x,y)的最短距离
private int bfs(int[][] grid, int[] tallPair, int[][] countCalc, int[][] distance, int tallCount) {
int[][] directors = new int[][]{
{0, 1}, {0, -1}, {-1, 0}, {1, 0}
};
int ans = Integer.MAX_VALUE;
Queue<int[]> queue = new LinkedList<>();
queue.add(tallPair);
while (!queue.isEmpty()) {
int[] pair = queue.poll();
int x = pair[0];
int y = pair[1];
int tempDistance = pair[2];
for (int i = 0; i < directors.length; i++) {
int nextX = x + directors[i][0];
int nextY = y + directors[i][1];
if (nextX < 0 || nextX > rows - 1 || nextY < 0 || nextY > cols - 1) {
continue;
}
// 如果不是空地就绕开其余情况都加入队列
if (grid[nextX][nextY] != 0) {
continue;
}
if (countCalc[nextX][nextY] != tallCount) {
continue;
}
int currentDis = tempDistance + 1;
queue.add(new int[]{nextX, nextY, currentDis});
countCalc[nextX][nextY] = tallCount + 1;
distance[nextX][nextY] = distance[nextX][nextY] + currentDis;
if (distance[nextX][nextY] < ans) {
ans = Math.min(ans, distance[nextX][nextY]);
}
}
}
return ans;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}

View File

@ -0,0 +1,56 @@
<p>给你一个 <code>m × n</code> 的网格,值为 <code>0</code><code>1</code><code>2</code> ,其中:</p>
<ul>
<li>每一个 <code>0</code> 代表一块你可以自由通过的 <strong>空地</strong>&nbsp;</li>
<li>每一个 <code>1</code> 代表一个你不能通过的 <strong>建筑</strong></li>
<li>每个 <code>2</code> 标记一个你不能通过的 <strong>障碍</strong>&nbsp;</li>
</ul>
<p>你想要在一块空地上建造一所房子,在 <strong>最短的总旅行距离</strong> 内到达所有的建筑。你只能上下左右移动。</p>
<p>返回到该房子的 <strong>最短旅行距离</strong> 。如果根据上述规则无法建造这样的房子,则返回 <code>-1</code></p>
<p><strong>总旅行距离&nbsp;</strong>是朋友们家到聚会地点的距离之和。</p>
<p>使用 <strong>曼哈顿距离</strong>&nbsp;计算距离,其中距离 <code>(p1, p2) = |p2.x - p1.x | + | p2.y - p1.y |</code></p>
<p>&nbsp;</p>
<p><strong>示例&nbsp; 1</strong></p>
<p><img src="https://assets.leetcode.com/uploads/2021/03/14/buildings-grid.jpg" /></p>
<pre>
<strong>输入:</strong>grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
<strong>输出:</strong>7
<strong>解析:</strong>给定<code>三个建筑物 (0,0)、</code><code>(0,4) 和</code> <code>(2,2) 以及一个</code>位于 <code>(0,2) 的障碍物。
由于总距离之和 3+3+1=7 最优,所以位置</code> <code>(1,2)</code> 是符合要求的最优地点。
故返回7。
</pre>
<p><strong>示例&nbsp;2:</strong></p>
<pre>
<strong>输入:</strong> grid = [[1,0]]
<strong>输出:</strong> 1
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong> grid = [[1]]
<strong>输出:</strong> -1
</pre>
<p>&nbsp;</p>
<p><strong>提示:</strong></p>
<ul>
<li><code>m == grid.length</code></li>
<li><code>n == grid[i].length</code></li>
<li><code>1 &lt;= m, n &lt;= 50</code></li>
<li><code>grid[i][j]</code>&nbsp;&nbsp;<code>0</code>,&nbsp;<code>1</code>&nbsp;&nbsp;<code>2</code></li>
<li><code>grid</code>&nbsp;<strong>至少</strong>&nbsp;<strong>一幢</strong> 建筑</li>
</ul>
<div><div>Related Topics</div><div><li>广度优先搜索</li><li>数组</li><li>矩阵</li></div></div><br><div><li>👍 118</li><li>👎 0</li></div>