【问题标题】:Knight's Tour - BackTracking in Java, Out of Bound [duplicate]Knight's Tour - Java 中的回溯,超出范围 [重复]
【发布时间】:2018-07-30 17:18:37
【问题描述】:

我正在尝试解决这个问题,即在给定 N * M 棋盘的情况下,Knight's Tour 被定义为 Knight 的移动序列,使得 Knight 只访问每个方格一次。下面是我的代码,但是我让 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;
}

【问题讨论】:

    标签: java recursion recursive-backtracking knights-tour


    【解决方案1】:

    您得到 exception 是因为您尝试使用超出数组范围的索引访问元素。

    发生这种情况是因为 isSafeMove 方法中的 if 语句没有按照您的意愿执行。

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

    您使用了&amp;&amp;,因此所有这些语句在其他情况下都需要为true 才能执行if 块,而不是&amp;&amp; 您应该在其他情况下使用|| 以使其在只有其中一种情况下才能工作是真的。

    像这样:

    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)
    

    【讨论】:

    • 但在这种情况下,如果当马在 (0,0) 时,雄蕊为 is(safe, board, 2,1) 返回 false,即使这是一个有效的移动。
    • -1 表示已访问或未访问字段?
    • 最初棋盘的所有索引都为零,同时回溯或删除我们在该位置放置 -1 的骑士,以便下次访问时我们知道该位置未被占用。(我也尝试制作再次发现 0,但这只会导致无限循环)
    • 只需将最后一个大小写更改为board[r][c] == -1,它应该可以工作。
    • 将最后一条语句更改为“==-1”,现在我得到这个输出 00000000 00000000 01000000 00000000 002040620 00000000 000306300 00000000
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多