【发布时间】:2021-11-29 07:47:08
【问题描述】:
我正在 LeetCode.com 上解决这个名为 Path With Minimum Effort 的问题:
给定高度,一个大小为行 x 列的二维数组,其中 heights[row][col] 表示单元格 (row, col) 的高度。目标是从左上角到右下角。您可以向上、向下、向左或向右移动,并且您希望找到一条需要最少努力的路线。路线的努力是路线的两个连续单元格之间的最大绝对高度差。返回从左上角单元格移动到右下角单元格所需的最小努力。例如,如果
heights = [[1,2,2],[3,8,2],[5,3,5]],则答案是2(绿色)。
我的代码是:
class Solution {
public:
vector<pair<int,int>> getNeighbors(vector<vector<int>>& h, int r, int c) {
vector<pair<int,int>> n;
if(r+1<h.size()) n.push_back({r+1,c});
if(c+1<h[0].size()) n.push_back({r,c+1});
if(r-1>=0) n.push_back({r-1,c});
if(c-1>=0) n.push_back({r,c-1});
return n;
}
int minimumEffortPath(vector<vector<int>>& heights) {
int rows=heights.size(), cols=heights[0].size();
using arr=array<int, 3>;
priority_queue<arr, vector<arr>, greater<arr>> pq;
vector<vector<int>> dist(rows, vector<int>(cols, INT_MAX));
pq.push({0,0,0}); //r,c,weight
dist[0][0]=0;
//Dijkstra
while(pq.size()) {
auto [r,c,wt]=pq.top();
pq.pop();
if(wt>dist[r][c]) continue;
vector<pair<int,int>> neighbors=getNeighbors(heights, r, c);
for(auto n: neighbors) {
int u=n.first, v=n.second;
int curr_cost=abs(heights[u][v]-heights[r][c]);
if(dist[u][v]>max(curr_cost,wt)) {
dist[u][v]=max(curr_cost,wt);
pq.push({u,v,dist[u][v]});
}
}
}
return dist[rows-1][cols-1];
}
};
这被接受了,但我有两个问题:
一个。既然我们更新dist[u][v],如果它大于 比max(curr_cost,wt),它如何保证最终我们返回所需的最小 努力?也就是说,我们为什么不最终回报上面红色的努力?
b.一些解决方案,例如this one,当我们第一次到达右下角时短路并立即返回(即if(r==rows-1 and c==cols-1) return wt;) - 这是如何工作的?当我们以后重新访问右下角节点时,我们不能得到更短的dist 吗?
【问题讨论】:
-
所以你写的代码你看不懂?
-
@ChrisMM,有很多 WA 用于找出
dist[u][v]>max(curr_cost,wt)条件,是的。 -
@Someone 哇,这就是我所说的高效学习。建议:最好用一些good books 来浪费你的时间。
-
您将首先从红色路径中获得 3,因为红色路径将首先从队列中出来(距离最后一次移动的距离为 1)。所以从最后 2 到 5 的移动将设置
dist[2][2] = 3。但是,当算法将探索绿色路径上 (row=2,col=1) 处的 3 时,您将拥有dist[2][2] = 3、curr_cost=2和wt=2。所以dist[2][2] > max(curr_cost, wt)和dist[2][2]减少到 2。所以是的,最短路径是具有 最小 最大绝对差异的路径。 -
@user3386109,完美!这回答了我的问题。如果您将其转换为答案,请告诉我。我会非常乐意接受它。再次感谢! :)
标签: c++ algorithm graph dijkstra graph-traversal