You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java递归实现Knight's Tour在5×5棋盘第5步卡住问题咨询

问题分析与解决方案

我一眼就看出你的代码卡壳的核心问题——递归遍历方向的逻辑写得太急躁了!在knightsTour的for循环里,你一找到第一个合法的移动位置就直接return递归结果,这相当于程序只敢走第一条看起来可行的路,完全不给自己留“回头换路”的机会。

举个具体的例子:当第5步走到最后一行时,明明有4个合法方向,但你的代码只会试第一个方向。如果这个方向是死胡同,程序直接就把当前位置重置回0并返回false,根本没机会尝试剩下的7个方向,自然就卡在这儿了。

修复后的完整代码

把for循环里的逻辑调整一下:不要急着return,先尝试这个方向,如果走通了再返回true;走不通就继续试下一个方向,直到所有方向都试过才回溯。另外我还顺手优化了几个小细节:

public class KnightsTour {
    public boolean isSafe(int[][] board, int y, int x) {
        // 把"未被访问"的判断直接整合到这里,避免重复检查
        if (y >= 0 && x >= 0 && y < board.length && x < board.length && board[y][x] == 0) {
            return true;
        }
        return false;
    }

    public boolean knightsTour(int[][] board, int y, int x, int move) {
        System.out.println("Move " + move + " happened!");
        board[y][x] = move;
        move++;

        // 修正终止条件:move从1开始,完成25步后会变成26,此时才是真的填满了棋盘
        if (move == board.length * board.length + 1) {
            return true;
        }

        int[][] moves = { {1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, -1}, {-2, 1} };

        for (int i = 0; i < moves.length; i++) {
            int newY = y + moves[i][0];
            int newX = x + moves[i][1];
            if (isSafe(board, newY, newX)) {
                // 先尝试这个方向,走通了就返回true,走不通就继续试下一个
                if (knightsTour(board, newY, newX, move)) {
                    return true;
                }
            }
        }

        // 所有方向都试过都走不通,回溯重置当前位置
        board[y][x] = 0;
        return false;
    }

    public static void main(String[] args) {
        KnightsTour tour = new KnightsTour();
        int[][] board = new int[5][5];
        // Java的int数组默认初始值就是0,不用手动循环赋值啦

        boolean isCompleted = tour.knightsTour(board, 0, 0, 1);
        System.out.println("巡游是否完成:" + isCompleted);

        // 打印最终棋盘
        System.out.println("Board:");
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                System.out.print(board[i][j] + "\t");
            }
            System.out.println("");
        }
    }
}

额外说明

  • 原来的终止条件move == board.length * board.length会提前一步结束,因为move从1开始,第25步时move是25,执行move++后才是26,这时候才代表所有位置都填满了。
  • isSafe方法里加入board[y][x] == 0的判断,让逻辑更紧凑,不用在递归开头再重复检查。

现在运行代码,程序会正确尝试所有可能的路径,最终完成5×5棋盘的骑士巡游。

内容的提问来源于stack exchange,提问作者J__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:23:51