Skip to content

Commit 77afc6c

Browse files
authored
Merge pull request soapyigu#346 from soapyigu/BFS
BFS Updates
2 parents 98319c0 + 4151885 commit 77afc6c

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

BFS/ShortestPathGetFood.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Question Link: https://leetcode.com/problems/shortest-path-to-get-food/
3+
* Primary idea: BFS to go over all possible word paths until the cell is food, avoid hitting the obstacle.
4+
*
5+
* Time Complexity: O(nm), Space Complexity: O(nm)
6+
*/
7+
8+
class ShortestPathGetFood {
9+
func getFood(_ grid: [[Character]]) -> Int {
10+
let m = grid.count, n = grid[0].count
11+
var isVisited = Array(repeating: Array(repeating: false, count: n), count: m)
12+
13+
let start = findStart(grid)
14+
15+
isVisited[start.0][start.1] = true
16+
var queue = [Point(i: start.0, j: start.1, len: 0)]
17+
18+
while !queue.isEmpty {
19+
let point = queue.removeFirst()
20+
21+
if grid[point.i][point.j] == "#" {
22+
return point.len
23+
}
24+
25+
for dir in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
26+
let (x, y) = (point.i + dir.0, point.j + dir.1)
27+
28+
guard x >= 0 && x < m && y >= 0 && y < n && !isVisited[x][y] else {
29+
continue
30+
}
31+
32+
if grid[x][y] == "X" {
33+
continue
34+
}
35+
36+
isVisited[x][y] = true
37+
queue.append(Point(i: x, j: y, len: point.len + 1))
38+
}
39+
}
40+
41+
return -1
42+
}
43+
44+
private func findStart(_ grid: [[Character]]) -> (Int, Int) {
45+
for i in 0..<grid.count {
46+
for j in 0..<grid[0].count {
47+
if grid[i][j] == "*" {
48+
return (i, j)
49+
}
50+
}
51+
}
52+
53+
return (-1, -1)
54+
}
55+
56+
struct Point {
57+
var i: Int
58+
var j: Int
59+
var len: Int
60+
}
61+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Question Link: https://leetcode.com/problems/shortest-path-in-a-grid-with-obstacles-elimination/
3+
* Primary idea: BFS to go over all possible word paths until the end. Choose the path only the remaining elimination number is greater.
4+
*
5+
* Time Complexity: O(nmk), Space Complexity: O(nm)
6+
*/
7+
8+
class ShortestPathGridObstaclesElimination {
9+
func shortestPath(_ grid: [[Int]], _ k: Int) -> Int {
10+
let m = grid.count, n = grid[0].count
11+
var remainings = Array(repeating: Array(repeating: -1, count: n), count: m)
12+
13+
remainings[0][0] = k
14+
var queue = [Point(i: 0, j: 0, remain: k)]
15+
var count = 0
16+
17+
if k > m + n - 2 {
18+
return m + n - 2;
19+
}
20+
21+
while !queue.isEmpty {
22+
23+
let currentPoints = queue
24+
queue.removeAll()
25+
26+
for point in currentPoints {
27+
if point.i == m - 1 && point.j == n - 1 {
28+
return count
29+
}
30+
31+
for dir in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
32+
let (x, y) = (point.i + dir.0, point.j + dir.1)
33+
34+
guard x >= 0 && x < m && y >= 0 && y < n else {
35+
continue
36+
}
37+
38+
if grid[x][y] == 1 && point.remain <= 0 {
39+
continue
40+
}
41+
42+
let remain = grid[x][y] == 1 ? point.remain - 1 : point.remain
43+
// only choose the path if remainings are greater
44+
if remainings[x][y] >= remain {
45+
continue
46+
}
47+
48+
remainings[x][y] = remain
49+
queue.append(Point(i: x, j: y, remain: remain))
50+
}
51+
}
52+
count += 1
53+
}
54+
55+
return -1
56+
}
57+
58+
struct Point {
59+
var i: Int
60+
var j: Int
61+
var remain: Int
62+
}
63+
}

0 commit comments

Comments
 (0)