Skip to content

Commit bc4c51a

Browse files
authored
Create 2812-find-the-safest-path-in-a-grid.js
1 parent 95601a4 commit bc4c51a

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* @param {number[][]} grid
3+
* @return {number}
4+
*/
5+
const maximumSafenessFactor = function (grid) {
6+
let n = grid.length,
7+
m = grid[0].length,
8+
ans = Infinity
9+
const { min, abs } = Math
10+
let t = []
11+
for (let i = 0; i < n; i++) {
12+
for (let j = 0; j < m; j++) {
13+
if (grid[i][j] == 1) {
14+
t.push([i, j]) // keeping track of each thief
15+
}
16+
}
17+
}
18+
19+
const vis = Array.from({ length: n }, () => Array(m).fill(0))
20+
21+
const pq = new PQ((a, b) => a[0] > b[0])
22+
let m_dist = Infinity
23+
for (const thieve of t) {
24+
m_dist = Math.min(m_dist, thieve[0] + thieve[1]) // Calculating Manhattan distance between current cell and all thieves
25+
}
26+
let dr = [0, -1, 0, 1],
27+
dc = [-1, 0, 1, 0]
28+
pq.push([m_dist, [0, 0]])
29+
vis[0][0] = 1
30+
// int mn_dist = 0;
31+
while (!pq.isEmpty()) {
32+
let temp = pq.pop()
33+
34+
let dist = temp[0],
35+
r = temp[1][0],
36+
c = temp[1][1]
37+
// mn_dist = min(dist,mn_dist);
38+
if (r == n - 1 && c == m - 1) {
39+
return dist // return path safety when end is reached
40+
}
41+
for (let i = 0; i < 4; i++) {
42+
let nr = r + dr[i]
43+
let nc = c + dc[i]
44+
if (nr >= 0 && nc >= 0 && nr < n && nc < m && !vis[nr][nc]) {
45+
//for every adjacent cell calculate the minimum mahattan distance betwwen cell and thieves.
46+
vis[nr][nc] = 1
47+
let m_dist = Infinity
48+
for (let thieve of t) {
49+
m_dist = min(m_dist, abs(thieve[0] - nr) + abs(thieve[1] - nc))
50+
}
51+
52+
// push the minimum of current distance and the minimum distance of the path till now
53+
pq.push([min(m_dist, dist), [nr, nc]])
54+
}
55+
}
56+
}
57+
return ans
58+
}
59+
60+
class PQ {
61+
constructor(comparator = (a, b) => a > b) {
62+
this.heap = []
63+
this.top = 0
64+
this.comparator = comparator
65+
}
66+
size() {
67+
return this.heap.length
68+
}
69+
isEmpty() {
70+
return this.size() === 0
71+
}
72+
peek() {
73+
return this.heap[this.top]
74+
}
75+
push(...values) {
76+
values.forEach((value) => {
77+
this.heap.push(value)
78+
this.siftUp()
79+
})
80+
return this.size()
81+
}
82+
pop() {
83+
const poppedValue = this.peek()
84+
const bottom = this.size() - 1
85+
if (bottom > this.top) {
86+
this.swap(this.top, bottom)
87+
}
88+
this.heap.pop()
89+
this.siftDown()
90+
return poppedValue
91+
}
92+
replace(value) {
93+
const replacedValue = this.peek()
94+
this.heap[this.top] = value
95+
this.siftDown()
96+
return replacedValue
97+
}
98+
99+
parent = (i) => ((i + 1) >>> 1) - 1
100+
left = (i) => (i << 1) + 1
101+
right = (i) => (i + 1) << 1
102+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
103+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
104+
siftUp = () => {
105+
let node = this.size() - 1
106+
while (node > this.top && this.greater(node, this.parent(node))) {
107+
this.swap(node, this.parent(node))
108+
node = this.parent(node)
109+
}
110+
}
111+
siftDown = () => {
112+
let node = this.top
113+
while (
114+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
115+
(this.right(node) < this.size() && this.greater(this.right(node), node))
116+
) {
117+
let maxChild =
118+
this.right(node) < this.size() &&
119+
this.greater(this.right(node), this.left(node))
120+
? this.right(node)
121+
: this.left(node)
122+
this.swap(node, maxChild)
123+
node = maxChild
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)