-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsolution.js
115 lines (93 loc) · 2.56 KB
/
solution.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* Convert land's adjacent waters into new lands, and return the new lands. This will mutate values in the input array.
* @param {*} input
* @param {*} land
*/
const getAdjacentLands = (input, land) => {
const nextLands = []
if (land.row - 1 >= 0) {
if (input[land.row - 1] && input[land.row - 1][land.col] === 0) {
input[land.row - 1][land.col] = 1
nextLands.push({ row: land.row - 1, col: land.col })
}
}
if (land.row + 1 < input.length) {
if (input[land.row + 1] && input[land.row + 1][land.col] === 0) {
input[land.row + 1][land.col] = 1
nextLands.push({ row: land.row + 1, col: land.col })
}
}
if (land.col - 1 >= 0) {
if (input[land.row][land.col - 1] === 0) {
input[land.row][land.col - 1] = 1
nextLands.push({ row: land.row, col: land.col - 1 })
}
}
const maxCol = input[land.row].length
if (land.col + 1 < maxCol) {
if (input[land.row][land.col + 1] === 0) {
input[land.row][land.col + 1] = 1
nextLands.push({ row: land.row, col: land.col + 1 })
}
}
return nextLands
}
/**
* Perform breadth-first search through the input array, converting 0 to 1 while calculating the distance from the original lands. This will mutate values in the input array.
* @param {*} input Array.
* @param {*} lands Current lands. Array of { row, col }.
* @param {Number} distance Current distance of lands.
*/
const getDistance = (input, lands, distance) => {
const nextLands = []
for (const land of lands) {
const tempNextLands = getAdjacentLands(input, land)
nextLands.push(...tempNextLands)
}
if (nextLands.length === 0) {
return distance
}
const nextDistance = distance + 1
return getDistance(input, nextLands, nextDistance)
}
/**
* Iterare through all cells in input[row][col] and returns { lands[{row, col}], hasLand, hasWater }.
* @param {*} input
*/
const getInitialInfo = (input) => {
const lands = []
let hasLand = false
let hasWater = false
for (let i = 0; i < input.length; i++) {
const eli = input[i]
for (let j = 0; j < eli.length; j++) {
const elj = eli[j]
if (elj === 1) {
hasLand = true
lands.push({
row: i,
col: j
})
}
if (elj === 0) {
hasWater = true
}
}
}
return {
lands,
hasLand,
hasWater
}
}
const maxDistance = (input) => {
const { lands, hasLand, hasWater } = getInitialInfo(input)
if (!hasWater) {
return -1
}
if (!hasLand) {
return -1
}
return getDistance(input, lands, 0)
}
module.exports = maxDistance