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 建筑物的最短距离的更多相关文章

  1. [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 ...

  2. LeetCode 317. Shortest Distance from All Buildings

    原题链接在这里:https://leetcode.com/problems/shortest-distance-from-all-buildings/ 题目: You want to build a ...

  3. 317. Shortest Distance from All Buildings

    题目: Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where th ...

  4. 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的值. 最 ...

  5. [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 ...

  6. [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 ...

  7. 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 ...

  8. 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 ...

  9. LeetCode 821 Shortest Distance to a Character 解题报告

    题目要求 Given a string S and a character C, return an array of integers representing the shortest dista ...

随机推荐

  1. ThinkPHP的路由规则和URL生成,结合django的URL理解

    这个知识点,我觉得蛮重要的. 不作任何路由定义的TP,URL格式和controller之间,相当于强绑定. 路由配置,让URL和controller的关系可以自定义. URL生成,让controlle ...

  2. pandas 常用方法使用示例

    from pandas import DataFrame import numpy as np import pandas as pd t={ , , np.nan, , np.nan, ], &qu ...

  3. LeetCode 1060. Missing Element in Sorted Array

    原题链接在这里:https://leetcode.com/problems/missing-element-in-sorted-array/ 题目: Given a sorted array A of ...

  4. gin+redis

    var RedisDefaultPool *redis.Pool func newPool(addr string) *redis.Pool { return &redis.Pool{ Max ...

  5. Linux系统硬盘扩容

    参考教程:https://www.jb51.net/article/144291.htm 1.查看硬盘已经用了99% $ df -h #查看硬盘已经使用了99% 文件系统 容量 已用 可用 已用% 挂 ...

  6. 实训作业5(lang、util)

    实验内容和原理: 1.将布尔型.整型.长整型.双精度型作为参数,实例化相应的包装类对象,并输出对象的数值. package 包装; public class integer { public stat ...

  7. CF1172E Nauuo and ODT LCT

    自己独立想出来的,超级开心 一开始想的是对于每一个点分别算这个点对答案的贡献. 但是呢,我们发现由于每一条路径的贡献是该路径颜色种类数,而每个颜色可能出现多次,所以这样就特别不好算贡献. 那么,还是上 ...

  8. 洛谷 P2212 [USACO14MAR]浇地Watering the Fields 题解

    P2212 [USACO14MAR]浇地Watering the Fields 题目描述 Due to a lack of rain, Farmer John wants to build an ir ...

  9. BZOJ 3435: [Wc2014]紫荆花之恋

    二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 ...

  10. 图解CRM(客户关系管理)全流程

    https://blog.csdn.net/lylmwt/article/details/84921432