思路
- 迷宫深度遍历
- 广度扩展8个方向
- 输出结果加1
- 如何存储step?——点位置对应方向
代码——时空复杂度高
步骤:
1.特殊情况处理 开头为1 或者 size为1
2.遍历队列,访问存储初始化
3.将迷宫开头压入队列,进行8个方向的广度遍历
4.到达目的 返回到迷宫开头的最小值
class Solution {
const int directionx[8] = { -1,1,0,0,-1,-1,1,1 };
const int directiony[8] = { 0,0,-1,1,-1,1,-1,1 };
public:
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
if (grid.size() == 1)
return 1;
if(grid[0][0]==1)
return -1;
int nr = grid.size(), nc = grid[0].size();
queue<pair<int, int>> Q;
map <pair<int, int>, int> seen;
Q.push({ 0,0 }); seen[{0, 0}] = 0;
int min=INT_MAX;
while (!Q.empty()) {
int curr = Q.front().first, curc = Q.front().second, step = seen[{curr, curc}]; Q.pop();
for (int i = 0; i < 8; ++i) {
int newx = curr + directionx[i], newy = curc + directiony[i];
if (newx < 0 || newx >= nr || newy < 0 || newy >= nc || seen.count({ newx,newy }) || grid[newx][newy] == 1)
continue;
if (newx == nr - 1 && newy == nc - 1)
min=seen[{curr, curc}] + 1<min?seen[{curr, curc}] + 1:min;
else {
Q.push({ newx,newy });
seen[{newx, newy}] = step + 1;
}
}
}
return min==INT_MAX? -1:min+1;
}
};
优化思路——双百
- 访问数组可否删除?——可以,将网格置为1,视作访问数组
- step可否不存储不断更新?——按照队列层次遍历,保证最短的距离最先找到
class Solution {
const int directionx[8] = { -1,1,0,0,-1,-1,1,1 };
const int directiony[8] = { 0,0,-1,1,-1,1,-1,1 };
public:
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
if (grid.size() == 1)
return 1;
if(grid[0][0]==1)
return -1;
int nr = grid.size(), nc = grid[0].size();
queue<pair<int, int>> Q;
Q.push({ 0,0 });grid[0][0]=1;
int step=0;
while (!Q.empty()) {
int len=Q.size();
++step;
while(len--){
int curr = Q.front().first, curc = Q.front().second;Q.pop();
for (int i = 0; i < 8; ++i) {
int newx = curr + directionx[i], newy = curc + directiony[i];
if (newx < 0 || newx >= nr || newy < 0 || newy >= nc || grid[newx][newy] == 1)
continue;
if (newx == nr - 1 && newy == nc - 1)
return step+1;
else {
Q.push({ newx,newy });
grid[newx][newy] = 1;
}
}
}
}
return -1;
}
};
收获
- 用迷宫本身作为访问数组,提高空间效率
- 对队列进行层次遍历,确保最快找到最短路径
- hash表类型不能为pair,因为pair没有实现hash的函数