Algorithm 棋盘上的骑士-最短路径
我试图解决这个问题: 基本上,你得到了一块板,一个起点和一个终点,你必须找到最短的路径。我正在试着在棋盘上做BFS,使用一个骑士可以做出的8个可能的移动,并返回它所采取的移动次数,或者-1,如果没有解决方案。我遇到运行时内存不足错误。我不确定错误(或潜在错误)发生在哪里 编辑:之前我遇到了一个错误,因为我忘了将节点标记为已访问。我已经把这个加进去了,但是我仍然没有得到正确的答案Algorithm 棋盘上的骑士-最短路径,algorithm,graph,depth-first-search,breadth-first-search,shortest-path,Algorithm,Graph,Depth First Search,Breadth First Search,Shortest Path,我试图解决这个问题: 基本上,你得到了一块板,一个起点和一个终点,你必须找到最短的路径。我正在试着在棋盘上做BFS,使用一个骑士可以做出的8个可能的移动,并返回它所采取的移动次数,或者-1,如果没有解决方案。我遇到运行时内存不足错误。我不确定错误(或潜在错误)发生在哪里 编辑:之前我遇到了一个错误,因为我忘了将节点标记为已访问。我已经把这个加进去了,但是我仍然没有得到正确的答案 public class Solution { private class Node {
public class Solution {
private class Node {
int row;
int col;
int count;
public Node() {
this.row = 0;
this.col = 0;
this.count = 0;
}
public Node(int row, int col, int count) {
this.row = row;
this.col = col;
this.count = count;
}
}
public int knight(int A, int B, int sr, int sc, int er, int ec) {
int[][] matrix = new int[A][B];
Queue<Node> q = new LinkedList<>(); //linkedlist??
Node n = new Node(sr, sc, 0);
q.add(n);
matrix[sr][sc] = -1;
final int[][] SHIFTS = {
{-2,1},
{-2,-1},
{2,1},
{2,-1},
{-1,2},
{-1,-2},
{1,2},
{1,-2}
};
int count = 0;
while(!q.isEmpty()) {
Node cur = q.remove();
if(cur.row == er && cur.col == ec) {
return cur.count;
}
for(int[] i : SHIFTS) {
if(canTraverse(matrix, cur.row + i[0], cur.col + i[1])) {
matrix[cur.row + i[0]][cur.col + i[1]] = -1;
q.add(new Node(cur.row + i[0], cur.col + i[1], cur.count + 1));
}
}
}
return -1;
}
public static boolean canTraverse(int[][] matrix, int sr, int sc) {
if(sr < 0 || sr >= matrix.length || sc < 0 || sc >= matrix[sr].length || matrix[sr][sc] == -1) {
return false;
}
return true;
}
}
公共类解决方案{
私有类节点{
int行;
int col;
整数计数;
公共节点(){
该行=0;
此值为0.col;
此值为0.count;
}
公共节点(整数行、整数列、整数计数){
this.row=行;
this.col=col;
this.count=计数;
}
}
公共整数骑士(整数A、整数B、整数sr、整数sc、整数er、整数ec){
int[][]矩阵=新的int[A][B];
队列q=新建LinkedList();//LinkedList??
节点n=新节点(sr,sc,0);
q、 添加(n);
矩阵[sr][sc]=-1;
最终整数[][]移位={
{-2,1},
{-2,-1},
{2,1},
{2,-1},
{-1,2},
{-1,-2},
{1,2},
{1,-2}
};
整数计数=0;
而(!q.isEmpty()){
节点cur=q.remove();
if(cur.row==er&&cur.col==ec){
返回当前计数;
}
对于(int[]i:SHIFTS){
if(canTraverse(矩阵,当前行+i[0],当前列+i[1])){
矩阵[cur.row+i[0]][cur.col+i[1]]=-1;
q、 添加(新节点(cur.row+i[0],cur.col+i[1],cur.count+1));
}
}
}
返回-1;
}
公共静态布尔canTraverse(int[][]矩阵,int sr,int sc){
如果(sr<0 | | sr>=矩阵。长度| | sc<0 | | sc>=矩阵[sr]。长度| |矩阵[sr][sc]=-1){
返回false;
}
返回true;
}
}
BFS算法需要标记每个访问的位置(节点)才能正常工作。否则,这样的代码可能导致(几乎可以肯定)运行时错误或超出内存限制(简而言之:A调用B,B调用A)
解决方案:创建一个布尔数组,并在节点进入队列时标记节点,完成此操作。我看不出在何处将空间标记为已访问。我将已访问节点的矩阵值改为-1,并将其作为不遍历节点的条件。但是,我没有得到正确的答案。@DisplayName请不要更改代码,因为您正在接近解决方案,因为这对其他人没有帮助,因为他们根本没有上下文。要得到正确答案,您必须在使用“q.add”的地方添加一行“matrix[row][col]=new_count”。这包括矩阵[sr][sc]=0。这是因为您需要在扩展BFS树时成功标记每个访问的节点。我不是让我访问的每个节点都使用for循环中的第一行-1吗?我不明白还有什么可以补充的。感谢您提供有关使用堆栈溢出的提示。@DisplayName是的,您将每个节点初始化为-1,但还需要更新遇到的每个节点的计算计数。查看wikipedia上的BFS伪代码,注意您的代码没有标记已发现的节点。请告诉我需要更改代码中的哪一行来修复它。我读过维基页面,仍然不确定。我以为我是通过将新节点值初始化为cur.count+1来更新每个节点的计算计数。再次感谢。