具体思想:
双向bfs,单向超时;
注意以下几个问题:
- 对于无给定边界,需要offset进行偏移计算;
- 双vis来记录相遇情况,vis可以充当步数记录;
- 优先进行元素小的队列;
具体代码:
class Solution {
public:
int minKnightMoves(int x, int y) {
int offset=304;
vector<vector<int>> visa(610,vector<int>(610,0));
vector<vector<int>> visb(610,vector<int>(610,0));
queue<pair<int,int>>qa;
queue<pair<int,int>>qb;
qa.push({0,0});
qb.push({x,y});
if(x==0&&y==0){
return 0;
}
while(!qa.empty()&&!qb.empty()){
if(qa.size()<=qb.size()){
int len=qa.size();
while(len>0){
len--;
auto pa=qa.front();
qa.pop();
int curx=pa.first;
int cury=pa.second;
if(visb[curx+offset][cury+offset]!=0){
return visa[curx+offset][cury+offset]+visb[curx+offset][cury+offset];
}
for(int i=0;i<8;i++){
int nx=curx+dir[i][0];
int ny=cury+dir[i][1];
if(nx+offset<0||ny+offset<0||nx+offset>609||ny+offset>609||visa[nx+offset][ny+offset]!=0)
continue;
qa.push({nx,ny});
visa[nx+offset][ny+offset]=visa[curx+offset][cury+offset]+1;
}
}
}else{
int len=qb.size();
while(len>0){
len--;
auto pa=qb.front();
qb.pop();
int curx=pa.first;
int cury=pa.second;
if(visa[curx+offset][cury+offset]!=0){
return visa[curx+offset][cury+offset]+visb[curx+offset][cury+offset];
}
for(int i=0;i<8;i++){
int nx=curx+dir[i][0];
int ny=cury+dir[i][1];
if(nx+offset<0||ny+offset<0||nx+offset>609||ny+offset>609||visb[nx+offset][ny+offset]!=0)
continue;
qb.push({nx,ny});
visb[nx+offset][ny+offset]=visb[curx+offset][cury+offset]+1;
}
}
}
}
return -1;
}
private:
vector<vector<int>> dir={{2,1},{1,2},{2,-1},{1,-2},{-2,1},{-1,2},{-2,-1},{-1,-2}};
};