Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:使用BFS获取二进制矩阵中的最短路径_Javascript_Algorithm_Graph_Breadth First Search - Fatal编程技术网

JavaScript:使用BFS获取二进制矩阵中的最短路径

JavaScript:使用BFS获取二进制矩阵中的最短路径,javascript,algorithm,graph,breadth-first-search,Javascript,Algorithm,Graph,Breadth First Search,我一直在使用JavaScript研磨leetcode,并试图解决这个问题 这个问题要求返回距离或最短路径的长度,我解决了这个问题。这是我的答案 var shortestPathBinaryMatrix=函数(网格){ 如果(网格[0][0]!=0)返回-1 常量队列=[[0,0],1]] const dest=[grid.length-1,grid[0].length-1] 已访问常量=新集合() const getNextSteps=([x,y])=>{ 常数dirs=[[1,0]、-1,0]

我一直在使用JavaScript研磨leetcode,并试图解决这个问题

这个问题要求返回距离或最短路径的长度,我解决了这个问题。这是我的答案

var shortestPathBinaryMatrix=函数(网格){
如果(网格[0][0]!=0)返回-1
常量队列=[[0,0],1]]
const dest=[grid.length-1,grid[0].length-1]
已访问常量=新集合()
const getNextSteps=([x,y])=>{
常数dirs=[[1,0]、-1,0]、[0,1]、[0,-1]、[1,1]、-1,1]、-1,-1]、[1,-1]]
const nextSteps=[]
for(dirs的常数[nx,ny]{
如果(网格[x+nx]?[y+ny]==0)下一步推送([x+nx,y+ny])
}
返回下一步
}
for(队列的常数[当前,距离]){
如果(visitor.has(curr.toString()))继续
如果(当前[0]==dest[0]&&curr[1]==dest[1]&&grid[dest[0]]][dest[1]]==0)返回距离
visited.add(curr.toString())
getNextSteps(curr).forEach(adj=>queue.push([adj,distance+1]))
}
返回-1
};
然而,我想知道我是否也能得到到达矩阵末端所需的实际路径,所以我不想返回一个数字作为路径的长度,而是想返回实际路径,它是它在短路径上访问的坐标数组

例如,如果输入网格是
[[0,0,0],[1,1,0],[1,1,0]]
,它应该返回
[[0,0],[0,1],[1,2],[2,2]] 


但这比看起来更难做到。我尝试了一些方法,但似乎无法解决它。有人可以试一试吗?

主要思想是将访问的
作为地图而不是集合,并将访问的节点路径上的上一个节点的坐标注册为值

为了实现这一点,我发现比您提前一步进行访问标记更容易:在将单元格放入队列时进行标记,而不是在将其从队列中拉出时进行标记

到达目的地后,可以将地图用作链接列表,然后沿着路径返回到源节点。这样就可以重建路径。然后就留下来扭转它

这是您的代码,修改后带有注释:

var shortestPathBinaryMatrix=函数(网格){
if(grid[0][0]!=0)返回[];//修改返回类型
常量队列=[[0,0],1]];
const dest=[grid.length-1,grid[0].length-1];
const visted=新映射();
visted.set([0,0].toString(),null);//将源标记为已访问
const getNextSteps=([x,y])=>{
常数dirs=[[1,0]、-1,0]、[0,1]、[0,-1]、[1,1]、-1,1]、-1,-1]、[1,-1];
const nextSteps=[];
for(dirs的常数[nx,ny]{
如果(网格[x+nx]?[y+ny]==0)下一步推送([x+nx,y+ny]);
}
返回下一步;
}
for(让队列[当前,距离]){
//将已访问的支票移至循环
如果(当前[0]==dest[0]&当前[1]==dest[1]&网格[dest[0]]][dest[1]]==0){
//从已访问结构中的链接列表中导出路径:
让路径=[];
while(curr){
路径推送(curr);
curr=visted.get(curr.toString());
}
return path.reverse();//需要反转才能从源到目标
}
for(让getNextSteps的调整(curr)){
//我把支票搬到这里来了:
如果(visitor.has(adj.toString()))继续;
//使用路径上上上一个节点的坐标进行标记:
visitored.set(adj.toString(),curr);
排队推送([adj,距离+1]);
}
}
return[];//还必须修改此值
};
//演示
设网格=[[0,0,0],[1,1,0],[1,1,0];
让结果=最短路径二进制矩阵(网格);
控制台日志(结果)