Skip to content

Commit 243dfb3

Browse files
committed
[BFS] Add a solution to Shortest Distance from All Buildings
1 parent fa42d63 commit 243dfb3

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Question Link: https://leetcode.com/problems/shortest-distance-from-all-buildings
3+
* Primary idea: Use BFS to caculate distance from building to all valid points, and
4+
* then figuare out the smallest one of all candidates
5+
*
6+
* Time Complexity: O((mn)^2), Space Complexity: O(mn)
7+
*
8+
*/
9+
10+
class ShortestDistanceAllBuildings {
11+
func shortestDistance(_ grid: [[Int]]) -> Int {
12+
guard grid.count > 0 && grid[0].count > 0 else {
13+
return -1
14+
}
15+
16+
let m = grid.count, n = grid[0].count
17+
var distances = Array(repeating: Array(repeating: 0, count: n), count: m), reachableNums = Array(repeating: Array(repeating: 0, count: n), count: m)
18+
var shortestDistance = Int.max, buildingNums = 0
19+
20+
for i in 0..<m {
21+
for j in 0..<n {
22+
if grid[i][j] == 1 {
23+
buildingNums += 1
24+
bfs(grid, &distances, &reachableNums, i, j)
25+
}
26+
}
27+
}
28+
29+
for i in 0..<m {
30+
for j in 0..<n {
31+
if reachableNums[i][j] == buildingNums {
32+
shortestDistance = min(shortestDistance, distances[i][j])
33+
}
34+
}
35+
}
36+
37+
return shortestDistance == Int.max ? -1 : shortestDistance
38+
}
39+
40+
fileprivate func bfs(_ grid: [[Int]], _ distances: inout [[Int]], _ reachableNums: inout [[Int]], _ i: Int, _ j: Int) {
41+
let m = grid.count, n = grid[0].count
42+
var pointsQueue = [(i, j)], distancesQueue = [0]
43+
var visited = Array(repeating: Array(repeating: false, count: n), count: m)
44+
45+
while !pointsQueue.isEmpty {
46+
let currentPoint = pointsQueue.removeFirst(), x = currentPoint.0, y = currentPoint.1
47+
let currentDistance = distancesQueue.removeFirst()
48+
let ranges = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
49+
50+
// set distances and reachableNums
51+
if grid[x][y] == 0 {
52+
distances[x][y] += currentDistance
53+
reachableNums[x][y] += 1
54+
}
55+
56+
// search neighbors
57+
for range in ranges {
58+
let xx = range.0, yy = range.1
59+
60+
guard xx >= 0 && xx < m && yy >= 0 && yy < n && !visited[xx][yy] else {
61+
continue
62+
}
63+
64+
guard grid[xx][yy] == 0 else {
65+
continue
66+
}
67+
68+
visited[xx][yy] = true
69+
pointsQueue.append((xx, yy))
70+
distancesQueue.append(currentDistance + 1)
71+
}
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)