这题还得好好看
参考题解:【多解法】DP + 二分+ BFS + 并查集
并查集
class Djset {
public:
vector<int> parent;
vector<int> rank;
Djset(int n): parent(n),rank(n)
{
for(int i=0;i<n;i++)
{
parent[i]=i;
}
}
int findfather(int x)
{
if(x!=parent[x])
parent[x]=findfather(parent[x]);
return parent[x];
}
void merge(int x,int y)
{
int fx=findfather(x);
int fy=findfather(y);
if(fx!=fy)
{
if(rank[fx]<rank[fy]) swap(fx,fy);
parent[fy]=fx;
if(rank[fx]==rank[fy]) rank[fx]+=1;
}
}
bool issame(int x,int y)
{
return findfather(x)==findfather(y);
}
};
struct Edge
{
int u,v,dis;
Edge(int _u,int _v,int _dis)
{
u=_u; v=_v; dis=_dis;
}
};
bool cmp(Edge a,Edge b)
{
return a.dis<b.dis;
};
class Solution {
public:
int minimumEffortPath(vector<vector<int>>& heights) {
int m=heights.size(),n=heights[0].size();
vector<Edge> edges;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i+1<m) edges.push_back(Edge(i*n+j,(i+1)*n+j,abs(heights[i][j]-heights[i+1][j])));
if(j+1<n) edges.push_back(Edge(i*n+j,i*n+j+1,abs(heights[i][j]-heights[i][j+1])));
}
}
sort(edges.begin(),edges.end(),cmp);
Djset ds(m*n);
int cost=0;
for(auto e:edges)
{
cost=e.dis;
ds.merge(e.u,e.v);
if(ds.issame(0,m*n-1)) break;
}
return cost;
}
};
二分+BFS:
class Solution {
public:
int dis[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
bool findfun(vector<vector<int>>& heights,int d)
{
int m=heights.size(),n=heights[0].size();
vector<bool> vis(m*n);
queue<int> q;
q.push(0);
while(!q.empty())
{
int cur=q.front(); q.pop();
if(vis[cur]) continue;
vis[cur]=true;
int r=cur/n,c=cur%n;
for(int i=0;i<4;i++)
{
int nr=r+dis[i][0];
int nc=c+dis[i][1];
if(nr>=m || nr<0 || nc>=n || nc<0 || vis[nr*n+nc] || abs(heights[r][c]-heights[nr][nc])>d) continue;
if(nr*n+nc==m*n-1) return true;
q.push(nr*n+nc);
}
}
return false;
}
int minimumEffortPath(vector<vector<int>>& heights) {
int l=0,r=1e6;
int cost=0;
while(l<=r)
{
int mid=l+(r-l)/2;
if(findfun(heights,mid))
{
r=mid-1;
cost=mid;
}
else
{
l=mid+1;
}
}
return cost;
}
};
BFS + DP
class Solution {
public:
int dis[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int minimumEffortPath(vector<vector<int>>& heights) {
int m = heights.size(),n = heights[0].size();
// 记录到起点到达该点的最小消耗体力
vector<vector<int>> dp(m,vector<int>(n,1e6));
dp[0][0]=0;
queue<int> q;
q.push(0);
while(!q.empty())
{
int cur=q.front(); q.pop();
int r=cur/n;
int c=cur%n;
for(int i=0;i<4;i++)
{
int nr=r+dis[i][0];
int nc=c+dis[i][1];
if(nr>=0 && nr<m && nc>=0 && nc<n)
{
int tmp=max(dp[r][c],abs(heights[r][c]-heights[nr][nc]));
if(tmp>=dp[nr][nc]) continue;
dp[nr][nc]=tmp;
q.push(nr*n+nc);
}
}
}
return dp[m-1][n-1];
}
};