-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPathWithMinimumEffort.java
71 lines (68 loc) · 2.42 KB
/
PathWithMinimumEffort.java
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
package com.namanh.binary_search;
import java.util.Stack;
/**
* https://leetcode.com/problems/path-with-minimum-effort
* A route's effort is the maximum absolute difference in heights between two consecutive cells of the route.
* Return the minimum effort required to travel from the top-left cell to the bottom-right cell.
*
* S1: Use binary search template
* S2: If you are given k, check if it is possible to go to (row-1, col-1) with k effort
* S2: Min effort is 0, max effort is maxValue - minValue, use binary search to find k
*
* Time: O(m * n * log(k)), k is maxVal - minVal
* Space: O(m * n)
*/
public class PathWithMinimumEffort {
public int minimumEffortPath(int[][] heights) {
int rows = heights.length;
int columns = heights[0].length;
int lo = 0;
int hi;
int mid;
int minVal = Integer.MAX_VALUE;
int maxVal = 0;
for (int[] height : heights) {
for (int i = 0; i < columns; i++) {
minVal = Math.min(height[i], minVal);
maxVal = Math.max(height[i], maxVal);
}
}
hi = maxVal - minVal;
while (lo < hi) {
mid = lo + (hi - lo) / 2;
if (tryAbsoluteDiff(heights, rows, columns, mid)) {
hi = mid;
} else {
lo = mid + 1;
}
}
return lo;
}
private boolean tryAbsoluteDiff(int[][] heights, int rows, int columns, int k) {
int[] dr = new int[]{0, 1, 0, -1};
int[] dc = new int[]{1, 0, -1, 0};
boolean[][] visited = new boolean[rows][columns];
Stack<int[]> stack = new Stack<>();
stack.push(new int[]{0,0});
while (!stack.isEmpty()) {
int[] pos = stack.pop();
int r = pos[0];
int c = pos[1];
if (r == rows - 1 && c == columns - 1) {
return true;
}
if (!visited[r][c]) {
visited[r][c] = true;
for (int i = 0; i < 4; i++) {
int newr = r + dr[i];
int newc = c + dc[i];
if (newr >= 0 && newr < rows && newc >= 0 && newc < columns && !visited[newr][newc]
&& Math.abs(heights[newr][newc] - heights[r][c]) <= k) {
stack.push(new int[]{newr, newc});
}
}
}
}
return false;
}
}