import
java.util.*;
public
class
MinimumEffortPath {
static
boolean
isPossible(Vector<Vector<Integer>> heights,
int
maxEffort,
int
rows,
int
columns) {
Vector<Vector<Integer>> dirs =
new
Vector<>();
dirs.add(
new
Vector<>(Arrays.asList(
0
,
1
)));
dirs.add(
new
Vector<>(Arrays.asList(
1
,
0
)));
dirs.add(
new
Vector<>(Arrays.asList(
0
, -
1
)));
dirs.add(
new
Vector<>(Arrays.asList(-
1
,
0
)));
Vector<Vector<Boolean>> visited =
new
Vector<>(rows);
for
(
int
i =
0
; i < rows; i++) {
visited.add(
new
Vector<>(columns));
for
(
int
j =
0
; j < columns; j++) {
visited.get(i).add(
false
);
}
}
Queue<Vector<Integer>> q =
new
LinkedList<>();
q.add(
new
Vector<>(Arrays.asList(
0
,
0
)));
visited.get(
0
).set(
0
,
true
);
while
(!q.isEmpty()) {
Vector<Integer> curr = q.poll();
if
(curr.get(
0
) == rows -
1
&& curr.get(
1
) == columns -
1
) {
return
true
;
}
for
(Vector<Integer> dir : dirs) {
int
newRow = curr.get(
0
) + dir.get(
0
);
int
newCol = curr.get(
1
) + dir.get(
1
);
if
(newRow >=
0
&& newRow < rows && newCol >=
0
&& newCol < columns
&& !visited.get(newRow).get(newCol)) {
int
heightDiff = Math.abs(heights.get(newRow).get(newCol) - heights.get(curr.get(
0
)).get(curr.get(
1
)));
if
(heightDiff <= maxEffort) {
q.add(
new
Vector<>(Arrays.asList(newRow, newCol)));
visited.get(newRow).set(newCol,
true
);
}
}
}
}
return
false
;
}
static
int
minimumEffortPath(Vector<Vector<Integer>> heights) {
int
rows = heights.size();
int
columns = heights.get(
0
).size();
int
left =
0
;
int
right = (
int
) 1e6;
while
(left < right) {
int
mid = left + (right - left) /
2
;
if
(isPossible(heights, mid, rows, columns)) {
right = mid;
}
else
{
left = mid +
1
;
}
}
return
left;
}
public
static
void
main(String[] args) {
Vector<Vector<Integer>> heights =
new
Vector<>();
heights.add(
new
Vector<>(Arrays.asList(
1
,
2
,
2
)));
heights.add(
new
Vector<>(Arrays.asList(
3
,
8
,
2
)));
heights.add(
new
Vector<>(Arrays.asList(
5
,
3
,
5
)));
int
result = minimumEffortPath(heights);
System.out.println(
"Minimum Effort: "
+ result);
}
}