题意分析
我刚看到这题就觉得和leetcode1368和2290很相似,基本做法就是个dijkstra算法。我刚开始想参照2290用层序遍历的做法,将同向的看作无障碍物,异向看作障碍物,进入下一层继续遍历,但是发现如果终点不在右下角,可能会提前输出。所以层序遍历的做法应该通常用于递增的路径,没负权的最短路还是dijkstra好用点吧。
算法思路
- 当作图,每个坐标点对于4周的点都有一条路径,与该点方向同向,则路径为0;异向则为1。
- 不断更新新的起点,更新以新的起点开始到四周的最短路。
- 最后返回起始点到终点的最短路。
代码实现
typedef array<int,3> AI3;
const int inf=INT_MAX/2;
class Solution {
public:
int conveyorBelt(vector<string>& matrix, vector<int>& start, vector<int>& end) {
int m=matrix.size();
int n=matrix[0].size();
vector<vector<int>> dist(m,vector<int>(n,inf));
priority_queue<AI3,vector<AI3>,greater<>> q;
q.push({0,start[0],start[1]});
vector<pair<int,int>> dirs={{0,1},{0,-1},{-1,0},{1,0}};
char s[5]={"><^v"};
while(!q.empty()){
auto [cost,i,j]=q.top();q.pop();
if(dist[i][j]<inf) continue;
dist[i][j]=cost;
for(int k=0;k<4;k++){
int x=i+dirs[k].first,y=j+dirs[k].second;
if(x<0||x>=m||y<0||y>=n) continue;
if(dist[x][y]<inf) continue;
int add=(matrix[i][j]==s[k]?0:1);
q.push({cost+add,x,y});
}
}
return dist[end[0]][end[1]];
}
};
解题总结
转化为图的2点最短路径问题,这道题就非常简单。这里的字符串映射也比较有技巧。