Leetcode 317. Shortest Distance from All Buildings [Hard]

Kostya
2 min readFeb 23, 2021

I wasn’t able to come up with better idea than brute force, surprisingly it worked. The idea of solution for this task is the foloowing:

  1. From every empty piece of land, let’s try to reach all building and calculate a distance.
  2. When we calculating a distance, I imagine that I make step in all available directions (similar like water moves from point in all directions)
  3. If on my move I find a building, than number of steps is a distance to this building, so I increate total number of steps to reach all building by this value.

Beside that, the algo is similar to tasks like count # of distinct islands.

class Solution {
class Coord{
int i;
int j;
public Coord(int i, int j) {
this.i = i;
this.j = j;
}
@Override
public int hashCode() { return i*1000+j; }
@Override
public boolean equals(Object obj) {
if(obj==null || !(obj instanceof Coord)) return false;
Coord c = (Coord) obj;
return c.i == this.i && c.j == this.j;
}
}

int[][] directions = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };

public int shortestDistance(int[][] grid) {
int numberOfBuildings = 0; // we need it to find how many building are there and locate unaccessed
Queue<Coord> emptyLand = new LinkedList<>();
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[0].length; j++) {
if(grid[i][j]==0) emptyLand.offer( new Coord(i , j) );
else if(grid[i][j]==1) numberOfBuildings++;
}
}

int minDis = Integer.MAX_VALUE;
while(!emptyLand.isEmpty()) {
Coord start = emptyLand.poll();
Set<Coord> visited = new HashSet<>();
Queue<Coord> bfs = new LinkedList<>();
bfs.offer(start);
visited.add(start);
int dis = 0;
int level = 0;
int buildingCount = 0;
while(!bfs.isEmpty()) {
int size = bfs.size();
for(int l = 0; l<size; l++) {
Coord c = bfs.poll();

if(grid[c.i][c.j]==1) {
buildingCount++;
dis += level;
continue;
}

for(int d=0; d<4;d++) {
int ni = c.i+directions[d][0];
int nj = c.j+directions[d][1];
Coord nc = new Coord(ni,nj);
if(ni>=0
&& ni<grid.length
&& nj>=0 && nj<grid[0].length
&& grid[ni][nj] != 2
&& !visited.contains(nc)) {
bfs.offer(nc);
visited.add(nc);
}
}
}
++level;
}

if(buildingCount == numberOfBuildings) {
minDis = Math.min(minDis, dis);
}

}


return minDis == Integer.MAX_VALUE ? -1: minDis;
}
}

--

--

Kostya

Java, start-up, hiking, photos, bicycle,journey