[LeetCode] 317. Shortest Distance from All Buildings 建筑物的最短距离
You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where:
- Each 0 marks an empty land which you can pass by freely.
- Each 1 marks a building which you cannot pass through.
- Each 2 marks an obstacle which you cannot pass through.
For example, given three buildings at (0,0)
, (0,4)
, (2,2)
, and an obstacle at (0,2)
:
1 - 0 - 2 - 0 - 1
| | | | |
0 - 0 - 0 - 0 - 0
| | | | |
0 - 0 - 1 - 0 - 0
The point (1,2)
is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.
Note:
There will be at least one building. If it is not possible to build such house according to the above rules, return -1.
给一个2纬网格,0代表空地可自由通过,1代表建筑物不能通过,2代表障碍物不可通过,找一个位置建房子,使其到所有建筑物的曼哈顿距离之和最小。返回建房子的位置,如果没有这样的位置返回-1。
解法:BFS,对于每一个建筑进行一次BFS计算到每一个可到达的空地的距离,然后对于每一个空地计算到所有建筑的距离和,求出距离和最短的空地。
Java:
public class Solution {
/**
* @param grid: the 2D grid
* @return: the shortest distance
*/
public int shortestDistance(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
} int m = grid.length, n = grid[0].length;
int[][] totalDistance = new int[m][n];
int step = 0, res = 0; for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
res = bfs(grid, i, j, step, totalDistance);
step--;
}
}
} return res == Integer.MAX_VALUE ? -1 : res;
} private int bfs(int[][] grid, int x, int y, int step, int[][] totalDistance) {
int res = Integer.MAX_VALUE, m = grid.length, n = grid[0].length;; Queue<Integer> queue = new LinkedList<>();
queue.offer(x * n + y); int curDis = 0;
int[] dirs = {-1, 0, 1, 0, -1}; while (!queue.isEmpty()) {
int l = queue.size();
curDis++;
while (l-- != 0) {
int t = queue.poll();
x = t / n;
y = t % n; for (int i = 0; i < 4; ++i) {
int _x = x + dirs[i], _y = y + dirs[i + 1];
if (_x >= 0 && _x < m && _y >= 0 && _y < n && grid[_x][_y] == step) {
queue.offer(_x * n + _y);
totalDistance[_x][_y] += curDis;
grid[_x][_y]--;
res = Math.min(res, totalDistance[_x][_y]);
}
}
}
}
return res;
}
}
Java:
public class Solution {
/**
* @param grid: the 2D grid
* @return: the shortest distance
*/
int len;
int m;
int n;
int count;
int sum;
int[] directions = {0, 1, 0, -1, 0};
public int shortestDistance(int[][] grid) {
// write your code here
m = grid.length;
n = grid[0].length;
if (grid == null || m == 0 || n == 0) {
return -1;
} int house = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
house++;
}
}
} count = 0;
len = 0;
sum = 0;
int minLen = Integer.MAX_VALUE;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 0) {
bfs(grid, i, j);
if (count != house) {
continue;
}else {
minLen = Math.min(minLen, sum);
}
}
}
}
return minLen == Integer.MAX_VALUE ? -1: minLen;
} private void bfs(int[][] grid, int i, int j) {
count = 0;
len = 0;
sum = 0;
Queue<Integer> q = new LinkedList<>();
Set<Integer> v = new HashSet<>();
q.offer(i * n + j);
v.add(i * n + j); while (!q.isEmpty()) {
len++;
int size = q.size();
while (size-- != 0) {
int cur = q.poll();
int x = cur / n;
int y = cur % n;
for (int k = 0; k < 4; ++k) {
int nx = x + directions[k];
int ny = y + directions[k + 1];
if (!v.contains(nx * n + ny) && nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] != 2) {
if (grid[nx][ny] == 1) {
count++;
sum += len;
v.add(nx * n + ny);
continue;
}
if (grid[nx][ny] == 0) {
q.offer(nx * n + ny);
v.add(nx * n + ny);
}
}
}
}
}
}
}
Python:
# Time: O(k * m * n), k is the number of the buildings
# Space: O(m * n) class Solution(object):
def shortestDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def bfs(grid, dists, cnts, x, y):
dist, m, n = 0, len(grid), len(grid[0])
visited = [[False for _ in xrange(n)] for _ in xrange(m)] pre_level = [(x, y)]
visited[x][y] = True
while pre_level:
dist += 1
cur_level = []
for i, j in pre_level:
for dir in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
I, J = i+dir[0], j+dir[1]
if 0 <= I < m and 0 <= J < n and grid[I][J] == 0 and not visited[I][J]:
cnts[I][J] += 1
dists[I][J] += dist
cur_level.append((I, J))
visited[I][J] = True pre_level = cur_level m, n, cnt = len(grid), len(grid[0]), 0
dists = [[0 for _ in xrange(n)] for _ in xrange(m)]
cnts = [[0 for _ in xrange(n)] for _ in xrange(m)]
for i in xrange(m):
for j in xrange(n):
if grid[i][j] == 1:
cnt += 1
bfs(grid, dists, cnts, i, j) shortest = float("inf")
for i in xrange(m):
for j in xrange(n):
if dists[i][j] < shortest and cnts[i][j] == cnt:
shortest = dists[i][j] return shortest if shortest != float("inf") else -1
C++:
class Solution {
public:
int shortestDistance(vector<vector<int>>& grid) {
int res = INT_MAX, val = 0, m = grid.size(), n = grid[0].size();
vector<vector<int>> sum = grid;
vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
for (int i = 0; i < grid.size(); ++i) {
for (int j = 0; j < grid[i].size(); ++j) {
if (grid[i][j] == 1) {
res = INT_MAX;
vector<vector<int>> dist = grid;
queue<pair<int, int>> q;
q.push({i, j});
while (!q.empty()) {
int a = q.front().first, b = q.front().second; q.pop();
for (int k = 0; k < dirs.size(); ++k) {
int x = a + dirs[k][0], y = b + dirs[k][1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == val) {
--grid[x][y];
dist[x][y] = dist[a][b] + 1;
sum[x][y] += dist[x][y] - 1;
q.push({x, y});
res = min(res, sum[x][y]);
}
}
}
--val;
}
}
}
return res == INT_MAX ? -1 : res;
}
};
C++:
class Solution {
public:
int shortestDistance(vector<vector<int>>& grid) {
int res = INT_MAX, buildingCnt = 0, m = grid.size(), n = grid[0].size();
vector<vector<int>> dist(m, vector<int>(n, 0)), cnt = dist;
vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
++buildingCnt;
queue<pair<int, int>> q;
q.push({i, j});
vector<vector<bool>> visited(m, vector<bool>(n, false));
int level = 1;
while (!q.empty()) {
int size = q.size();
for (int s = 0; s < size; ++s) {
int a = q.front().first, b = q.front().second; q.pop();
for (int k = 0; k < dirs.size(); ++k) {
int x = a + dirs[k][0], y = b + dirs[k][1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 0 && !visited[x][y]) {
dist[x][y] += level;
++cnt[x][y];
visited[x][y] = true;
q.push({x, y});
}
}
}
++level;
}
}
}
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 0 && cnt[i][j] == buildingCnt) {
res = min(res, dist[i][j]);
}
}
}
return res == INT_MAX ? -1 : res;
}
};
类似题目:
[LeetCode] 286. Walls and Gates 墙和门
[LeetCode] 296. Best Meeting Point 最佳开会地点
All LeetCode Questions List 题目汇总
[LeetCode] 317. Shortest Distance from All Buildings 建筑物的最短距离的更多相关文章
- [LeetCode] Shortest Distance from All Buildings 建筑物的最短距离
You want to build a house on an empty land which reaches all buildings in the shortest amount of dis ...
- LeetCode 317. Shortest Distance from All Buildings
原题链接在这里:https://leetcode.com/problems/shortest-distance-from-all-buildings/ 题目: You want to build a ...
- 317. Shortest Distance from All Buildings
题目: Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where th ...
- leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
542. 01 Matrix https://www.cnblogs.com/grandyang/p/6602288.html 将所有的1置为INT_MAX,然后用所有的0去更新原本位置为1的值. 最 ...
- [Locked] Shortest Distance from All Buildings
Shortest Distance from All Buildings You want to build a house on an empty land which reaches all bu ...
- [LeetCode] 821. Shortest Distance to a Character_Easy tag: BFS
Given a string S and a character C, return an array of integers representing the shortest distance f ...
- Shortest Distance from All Buildings
You want to build a house on an empty land which reaches all buildings in the shortest amount of dis ...
- LeetCode 613. Shortest Distance in a Line
Table point holds the x coordinate of some points on x-axis in a plane, which are all integers. Writ ...
- LeetCode 821 Shortest Distance to a Character 解题报告
题目要求 Given a string S and a character C, return an array of integers representing the shortest dista ...
随机推荐
- Java 出现cannot be resolved to a type
package com.sysutil.util; /* thishi duo zhu */ // dan zhshi import com.sysutil.util.*; class Example ...
- synchronize——对象锁和类锁
最近在研究Java 多线程的只是,经常能看到synchronize关键字,以前只是一眼带过,没有细究,今天趁这个机会,整理下 synchronize作为多线程关键字,是一种同步锁,它可以修饰以下几种对 ...
- RDD&Dataset&DataFrame
Dataset创建 object DatasetCreation { def main(args: Array[String]): Unit = { val spark = SparkSession ...
- Spring boot jpa 设定MySQL数据库的自增ID主键值
内容简介 本文主要介绍在使用jpa向数据库添加数据时,如果表中主键为自增ID,对应实体类的设定方法. 实现步骤 只需要在自增主键上添加@GeneratedValue注解就可以实现自增,如下图: 关键代 ...
- git工具免密拉取、推送
很苦恼每次都要配置明文密码才能正常工作 其实也可以配置成非明文 打开控制面板 →用户账号 管理 Windows凭证 对应修改响应网址即可
- 机器学习---逻辑回归(二)(Machine Learning Logistic Regression II)
在<机器学习---逻辑回归(一)(Machine Learning Logistic Regression I)>一文中,我们讨论了如何用逻辑回归解决二分类问题以及逻辑回归算法的本质.现在 ...
- Freemarker的简单demo
第一步.导入依赖 <dependency> <groupId>org.freemarker</groupId> <artifactId>freemark ...
- POI报表打印
一.Excel报表(POI) 1.需求说明 在企业级应用开发中,Excel报表是一种最常见的报表需求.Excel报表开发一般分为两种形式: 1.为了方便操作,基于Excel的报表批量上传数据 2.通过 ...
- automapper 源中有多个属性类映射到同一个 目标中
CreateMap<TempBranchActivity, BranchActivityOutput>() .ConstructUsing((src, ctx) => ctx.Map ...
- AOP通知类型
AOP通知类型 前置通知 在目标方法执行之前进行操作 后置通知 在目标方法执行之后 进行操作 环绕通知 在目标方法执行之前 和之后进行操作 public Object arount() 异常抛出通知 ...