You are a hiker preparing for an upcoming hike. You are given heights
, a 2D array of size rows x columns
, where heights[row][col]
represents the height of cell (row, col)
. You are situated in the top-left cell, (0, 0)
, and you hope to travel to the bottom-right cell, (rows-1, columns-1)
(i.e., 0-indexed). You can move up, down, left, or right, and you wish to find a route that requires the 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.
Example 1:
Input: heights = [[1,2,2],[3,8,2],[5,3,5]] Output: 2 Explanation: The route of [1,3,5,3,5] has a maximum absolute difference of 2 in consecutive cells. This is better than the route of [1,2,2,2,5], where the maximum absolute difference is 3.
Example 2:
Input: heights = [[1,2,3],[3,8,4],[5,3,5]] Output: 1 Explanation: The route of [1,2,3,4,5] has a maximum absolute difference of 1 in consecutive cells, which is better than route [1,3,5,3,5].
Example 3:
Input: heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]] Output: 0 Explanation: This route does not require any effort.
Constraints:
rows == heights.length
columns == heights[i].length
1 <= rows, columns <= 100
1 <= heights[i][j] <= 106
最小體力消耗路徑。
你准備參加一場遠足活動。給你一個二維 rows x columns 的地圖 heights ,其中 heights[row][col] 表示格子 (row, col) 的高度。一開始你在最左上角的格子 (0, 0) ,且你希望去最右下角的格子 (rows-1, columns-1) (注意下標從 0 開始編號)。你每次可以往 上,下,左,右 四個方向之一移動,你想要找到耗費 體力 最小的一條路徑。
一條路徑耗費的 體力值 是路徑上相鄰格子之間 高度差絕對值 的 最大值 決定的。
請你返回從左上角走到右下角的最小 體力消耗值 。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/path-with-minimum-effort
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
這是一道圖論/搜索的題,我直接給思路。這道題的解法涉及到Dijikstra算法,因為這道題求的是帶權重的圖的traverse問題。根據題意,圖的每一條邊的權重是由每兩個相鄰的cell.val的差的絕對值產生的,我們要找的是一條路徑能從起點走到終點同時在這條路徑上的花費是最小的。這條路徑的花費是某兩個節點/cell之間差值的最大值。
至於具體做法,我們會用到BFS。首先我們創建一個和input matrix等長等寬的matrix,記錄traverse到每個坐標的花費是多少。我們需要一個最小堆記錄[cost, row, col]。當我們遍歷到某個坐標的時候,如果已經記錄的effort更小則無需更新;如果重新計算的newEffort更小則需要更新effort數組並用這個值代入下一輪的BFS計算。
時間O(m * n * nlogn)
空間O(mn)
Java實現
1 class Solution { 2 public int minimumEffortPath(int[][] heights) { 3 int m = heights.length; 4 int n = heights[0].length; 5 int[][] effort = new int[m][n]; 6 for (int i = 0; i < m; i++) { 7 Arrays.fill(effort[i], Integer.MAX_VALUE); 8 } 9 // dist, row, col 10 PriorityQueue<int[]> queue = new PriorityQueue<>((a, b) -> a[0] - b[0]); 11 queue.offer(new int[] { 0, 0, 0 }); 12 int[][] dirs = new int[][] { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; 13 while (!queue.isEmpty()) { 14 int[] min = queue.poll(); 15 int dist = min[0]; 16 int row = min[1]; 17 int col = min[2]; 18 //此時的花費大於已經記錄下來的花費了,不用看了 19 if (dist > effort[row][col]) { 20 continue; 21 } 22 // traverse到終點了 23 if (row == m - 1 && col == n - 1) { 24 return dist; 25 } 26 for (int[] dir : dirs) { 27 int newRow = row + dir[0]; 28 int newCol = col + dir[1]; 29 if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n) { 30 // 新的cost 31 int newDist = Math.max(dist, Math.abs(heights[newRow][newCol] - heights[row][col])); 32 // 如果新的cost小於已經記錄的cost,就更新 33 if (newDist < effort[newRow][newCol]) { 34 effort[newRow][newCol] = newDist; 35 queue.offer(new int[] { newDist, newRow, newCol }); 36 } 37 } 38 } 39 } 40 return -1; 41 } 42 }
相關題目
1102. Path With Maximum Minimum Value