前言
一开始虽然知道将已经访问过的格子设置为墙,但是没有完全弄清楚是在哪里设置。其实在遍历周围4个点的时候,只要它不是边界空格子,就可以把它设置为墙。我就是在这里超时了。对照着官方题解才找到原因。
代码
实现了2个版本,一个比较简洁,一个可以打印路径
/*
* @lc app=leetcode.cn id=1926 lang=cpp
*
* [1926] 迷宫中离入口最近的出口
*/
// @lc code=start
#include<vector>
#include<tuple>
#include<queue>
using namespace std;
#include<iostream>
struct HWPos
{
int h;
int w;
HWPos* father;
};
class Solution {
public:
int nearestExit(vector<vector<char>>& maze, vector<int>& entrance)
{
#if 0 //不显示路径的做法
int rows = maze.size();
int cols = maze[0].size();
queue<tuple<int,int,int>> q; // [h,w], step
q.emplace(entrance[0],entrance[1],0);
//maze[entrance[0]][entrance[1]] = '+';
int a[4] = {1,-1,0,0};
int b[4] = {0, 0,-1,1};
while(q.empty() == false)
{
//int h, w, d;
auto [h,w,d] = q.front();
q.pop();
// 是否是终点
if(h==0 || h==rows-1 || w==0 || w==cols-1)
{
if(d > 0) return d;
}
// 置为墙
maze[h][w] = '+';
//
for(int i=0 ;i<4; ++i)
{
int newh = h + a[i];
int neww = w + b[i];
// 是否合法
if(newh>=0 && newh < rows && neww>=0 && neww < cols && maze[newh][neww]!='+')
{
if(newh==0 || newh==rows-1 || neww==0 || neww==cols-1)
{
return d+1;
}
else
{
q.emplace(newh,neww, d+1);
maze[newh][neww] = '+';
}
}
}
}
return -1;
#endif
#if 1 //显示路径的做法
int rows = maze.size();
int cols = maze[0].size();
queue<HWPos*> q;
HWPos* start = new HWPos;
start->h = entrance[0]; start->w = entrance[1];
start->father = nullptr;
maze[entrance[0]][entrance[1]] = '+';
q.emplace(start);
HWPos* end = new HWPos; bool findend = false;
while(q.empty()==false)
{
HWPos* curPos = q.front();
q.pop();
int dh[4]{-1,1,0,0};
int dw[4]{0,0,1,-1};
for(int i=0; i<4; ++i)
{
int newh = curPos->h + dh[i];
int neww = curPos->w + dw[i];
// 判断是否合法
if(newh>=0 && newh<rows && neww>=0 && neww<cols && maze[newh][neww]!='+')
{
HWPos* newpos = new HWPos;
newpos->father = curPos;
newpos->h = newh; newpos->w = neww;
if(newh==0 || newh==rows-1 || neww==0 || neww==cols-1)
{
findend = true;
end->father = curPos;
end->h = newh; end->w = neww;
delete newpos;
break;
}
else
{
// 普通白格子
maze[newh][neww] = '+';
q.push(newpos);
}
}
}
if(findend==true) break;
}
if(findend==true)
{
int step = 0;
cout<<"end to start path: "<<endl;
cout<<"["<<end->h<<","<<end->w<<"]<-";
while(end->father!=nullptr)
{
HWPos * tmp = end; // 先让end指向别的地方
end = end->father;
if(end->father!=nullptr)cout<<"["<<end->h<<","<<end->w<<"]<-";
else cout<<"["<<end->h<<","<<end->w<<"]"<<endl;
delete tmp; // 释放之前的end指向的地方
step +=1;
}
// 说明已经到了start
delete end;
return step;
}
return -1;
#endif
}
};
// @lc code=end
Accepted
194/194 cases passed (104 ms)
Your runtime beats 72.23 % of cpp submissions
Your memory usage beats 26.35 % of cpp submissions (33.1 MB)