Knight's Tour-Java中的BackTracking,超出范围

时间:2018-07-30 17:18:38

标签: java recursion recursive-backtracking

我正在尝试解决以下问题:问题在于,给定N * M的棋盘,将“骑士巡回赛”定义为骑士移动的顺序,以使骑士只能在每个广场上造访一次。下面是我的代码,但是我使Array越界= 8,我知道Moves试图在当前行中将值2与6相加时出现,但是我不确定如何摆脱它。

int MaxMove = 64; // for 8*8 chess Board
private int Moves[][] = new int[][] {{2, 1}, {2, -1}, {1, 2}, {1, -2}, {-2, 1}, {-2, -1}, {-1, 2}, {-1, -2}};

void solveKnightTour(int[][] board)
{
    knightsTourUtil(board, 0, 0, 1);
}

private boolean isSafeMove(int[][] board, int r, int c)
{
    if(r < 0 && r > board.length-1 && c < 0 && c > board.length-1 &&  board[r][c] != -1)
        return false;
    return true;
}

private boolean knightsTourUtil(int[][] board, int presentRow, int presentCol, int KthMove)
{
    if (KthMove >= MaxMove)
    {
        return true;
    }
    for (int i = 0; i < Moves.length; i++)
    {
        int nextRow = presentRow + Moves[i][0];
        int nextCol = presentCol + Moves[i][1];
        if (isSafeMove(board, nextRow, nextCol))
        {
            board[nextRow][nextCol] = KthMove;
            if (knightsTourUtil(board, nextRow, nextCol, KthMove + 1)) 
                return true;
            else
                board[nextRow][nextCol] = -1;
        }
    }
    return false;
}

1 个答案:

答案 0 :(得分:1)

之所以得到exception,是因为您尝试访问索引超出数组范围的元素。

之所以会发生这种情况,是因为if方法中的isSafeMove语句没有执行您想要的操作。

if(r < 0 && r > board.length-1 && c < 0 && c > board.length-1 &&  board[r][c] != -1)

您使用了&&,因此所有这些语句都需要放在其他true中才能执行if块,而不是&&,而应该在其他||中使用如果只有其中一种情况是正确的,那么它就会起作用。

像这样:

if(r < 0 || r > board.length-1 || c < 0 || c > board.length-1 ||  board[r][c] != -1)

编辑 起初,我假设-1用于非访问字段,但事实证明-1是用于访问字段。 如果应如下所示:

if(r < 0 || r > board.length-1 || c < 0 || c > board.length-1 ||  board[r][c] == -1)