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

Java八皇后问题递归无输出解排查:递归是否仅走单一路径?

你的八皇后问题无输出?我帮你揪几个关键bug

嘿,刚重新学Java就练八皇后,挺棒的!我看了你的代码片段和疑问,大概率是这几个问题导致没输出解,甚至让你觉得递归只走单一路径:

1. 二维数组克隆踩了浅拷贝的坑

你写的char[][] newBoard = board.clone();是个典型的新手坑——Java里二维数组的clone()只会克隆外层数组,里面的每一行还是和原board共用同一个数组对象。也就是说,你改newBoard[row][i]的时候,原board的对应位置也会被改掉!这直接打乱了回溯逻辑,后续递归的位置判断全错了,看起来就像递归只走了一条路。

正确的深拷贝应该逐行复制:

char[][] newBoard = new char[board.length][];
for (int j = 0; j < board.length; j++) {
    newBoard[j] = board[j].clone(); // 把每一行单独克隆一遍
}

2. 递归终止条件大概率没写

你没贴全代码,但八皇后递归必须有终止条件:当row == 8(所有行都放好皇后)时,要打印当前棋盘。如果没这个逻辑,就算递归走通了,也不会有任何输出。比如在solve方法开头加:

if (row == 8) {
    printBoard(board); // 自己写个打印棋盘的方法
    return;
}

3. 关于你问的「递归是否仅走单一路径」

正常八皇后是回溯递归:每一行尝试所有合法列,放皇后后递归下一行,递归返回后回溯恢复状态。但你因为浅拷贝污染了原棋盘,导致后续列的尝试都在被修改过的棋盘上进行,自然走不通其他路径。另外,如果你invalidate方法没正确标记皇后的攻击范围(同一列、两条对角线),那后续行找不到合法位置,递归就提前终止了,也会没输出。

给你个修正后的核心代码参考

我把关键部分改好,你可以对照着调:

public void solve(char[][] board, int row) {
    // 终止条件:所有行都放完皇后,输出解
    if (row == board.length) {
        printBoard(board);
        return;
    }

    for (int col = 0; col < 8; col++) {
        // 先判断当前位置能不能放皇后(比直接看board[row][col]更可靠)
        if (canPlaceQueen(board, row, col)) {
            // 深拷贝棋盘,避免污染原数据
            char[][] newBoard = new char[8][];
            for (int j = 0; j < 8; j++) {
                newBoard[j] = board[j].clone();
            }
            // 放皇后
            newBoard[row][col] = 'q';
            // 标记攻击范围(或者你也可以每次判断时实时检查,不用提前标记)
            markInvalidPositions(newBoard, row, col);
            // 递归处理下一行
            solve(newBoard, row + 1);
        }
    }
}

// 检查(row,col)能不能放皇后
private boolean canPlaceQueen(char[][] board, int row, int col) {
    // 检查同一列有没有皇后
    for (int i = 0; i < row; i++) {
        if (board[i][col] == 'q') return false;
    }
    // 检查左上到右下的对角线
    for (int i = row-1, j = col-1; i >=0 && j >=0; i--, j--) {
        if (board[i][j] == 'q') return false;
    }
    // 检查右上到左下的对角线
    for (int i = row-1, j = col+1; i >=0 && j <8; i--, j++) {
        if (board[i][j] == 'q') return false;
    }
    return true;
}

// 打印棋盘的辅助方法
private void printBoard(char[][] board) {
    for (char[] row : board) {
        System.out.println(new String(row));
    }
    System.out.println("==========");
}

这样改完后,应该就能看到八皇后的所有解输出了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:37:04