您的位置:首页 > 产品设计 > UI/UE

LeetCode 317. Shortest Distance from All Buildings(最短建筑距离)

2016-04-23 09:18 573 查看
原题网址:https://leetcode.com/problems/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.
方法:从每一栋建筑出发,广度优先搜索,更新该建筑到各块空地的距离。另外一个诀窍就是如果有两栋建筑之间不连通,则直接返回-1。

public class Solution {
private int[] r = {-1, 1, 0, 0};
private int[] c = {0, 0, -1, 1};

private boolean update(int[][] grid, int buildings, int row, int col, int[][] reach, int[][] distance) {
boolean[][] visited = new boolean[grid.length][grid[0].length];
Position position = new Position(row, col, 0);
Position tail = position;
visited[row][col] = true;
int reached = 1;
while (position != null) {
distance[position.row][position.col] += position.distance;
for(int i=0; i<4; i++) {
int y = position.row + r[i];
int x = position.col + c[i];
if (y >= 0 && y < grid.length && x >= 0 && x < grid[y].length && !visited[y][x]) {
visited[y][x] = true;
if (grid[y][x] == 1) {
reached ++;
} else if (grid[y][x] == 0) {
reach[y][x] ++;
tail.next = new Position(y, x, position.distance + 1);
tail = tail.next;
}
}
}
position = position.next;
}
// System.out.printf("row=%d, col=%d, reached=%d, buildings=%d\n", row, col, reached, buildings);
return reached == buildings;
}

public int shortestDistance(int[][] grid) {
int[][] distance = new int[grid.length][grid[0].length];
int[][] reach = new int[grid.length][grid[0].length];
int buildings = 0;
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j] == 1) buildings ++;
}
}
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j] == 1) {
if (!update(grid, buildings, i, j, reach, distance)) return -1;
}
}
}
// System.out.println();
// for(int i=0; i<grid.length; i++) {
//     for(int j=0; j<grid[i].length; j++) System.out.print(distance[i][j]+",");
//     System.out.println();
// }
int min = -1;
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j] == 0 && reach[i][j] == buildings && (min == -1 || distance[i][j] < min)) min = distance[i][j];
}
}
return min;
}
}
class Position {
int row, col;
int distance;
Position next;
Position(int row, int col, int distance) {
this.row = row;
this.col = col;
this.distance = distance;
}
}


另一种实现:

public class Solution {
private int[] ro = {-1, 1, 0, 0};
private int[] co = {0, 0, -1, 1};
private int br, bc;
private int go(int[][] grid, boolean[][] visit, int row, int col) {
int count = 0;
if (visit[row][col] || grid[row][col] == 2) return 0;
if (grid[row][col] == 1) {
visit[row][col] = true;
return 1;
}
visit[row][col] = true;
for(int i=0; i<4; i++) {
int r = row + ro[i];
int c = col + co[i];
if (r>=0 && r<grid.length && c>=0 && c<grid[r].length) count += go(grid, visit, r, c);
}
return count;
}
private int buildings(int[][] grid) {
int count = 0;
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j] == 1) {
br = i;
bc = j;
count ++;
}
}
}
return count;
}
private void calc(int[][] grid, int[][] total, int[][] reach, int row, int col) {
int[][] dist = new int[grid.length][grid[0].length];
LinkedList<Step> queue = new LinkedList<>();
queue.add(new Step(row, col, 0));
while (!queue.isEmpty()) {
Step step = queue.remove();
for(int i=0; i<4; i++) {
int r = step.row+ro[i];
int c = step.col+co[i];
if (r>=0 && r<grid.length && c>=0 && c<grid[r].length && dist[r][c]==0 && grid[r][c]==0) {
dist[r][c] = step.step+1;
total[r][c] += dist[r][c];
reach[r][c] ++;
queue.add(new Step(r, c, step.step+1));
}
}
}
}
public int shortestDistance(int[][] grid) {
int buildings = buildings(grid);
int go = 0;
boolean[][] visit = new boolean[grid.length][grid[0].length];
for(int i=0; i<4; i++) {
int r = br+ro[i];
int c = bc+co[i];
if (r>=0 && r<grid.length && c>=0 && c<grid[r].length && grid[r][c]==0) {
go += go(grid, visit, r, c);
}
}
if (buildings != go) return -1;
int[][] total = new int[grid.length][grid[0].length];
int[][] reach = new int[grid.length][grid[0].length];
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j]==1) {
calc(grid, total, reach, i, j);
}
}
}
int min = Integer.MAX_VALUE;
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[i].length; j++) {
if (grid[i][j]==0 && reach[i][j]==buildings) min = Math.min(min, total[i][j]);
}
}
return min;
}
}
class Step {
int row, col, step;
Step(int row, int col, int step) {
this.row = row;
this.col = col;
this.step = step;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: