算法 - N Queens Stack Overflow

时间:2015-01-07 23:32:41

标签: java algorithm

我正在尝试编写一个回溯代码,该代码将在NQueens问题中找到解决方案的数量。但是当我试图标记对角线网格时,我发现堆叠溢出是不安全的。“

int dim;

private void recurseMark(int row, int col, boolean[][] board, boolean val) {
    if(row >= dim || col >= dim || row < 0 || col < 0) return;
    if(board[row][col]) return;
    System.out.println("Row " + row + " Col " + col);
    board[row][col] = val;
    recurseMark(row+1, col-1, board, val);
    recurseMark(row+1, col+1, board, val);
    recurseMark(row-1, col+1, board, val);
    recurseMark(row-1, col-1, board, val);
}

private void mark(int i, int k, boolean[][] board, boolean val) {
     for(int j = 0; j < dim; j++) {
        board[i][j] = val;
    }

    for(int j = 0; j < dim; j++) {
        board[j][k] = val;
    }
}

private int countQueens(int i, boolean[][] board) {
    int count = 0;

    if(i == dim) return 1;

    for(int k = 0; k < dim; k++) {
        if(!board[i][k]) {
            board[i][k] = true;
            mark(i, k, board, true);
            System.out.println("Giving " + i + " " + k);
            recurseMark(i, k, board, true);
            count += countQueens(i+1, board);    
            recurseMark(i, k, board, false);
            mark(i, k, board, false);
        }
    }

    return count;
}


public int totalNQueens(int n) {
    dim = n;

    boolean[][] board = new boolean[n][n];

    return countQueens(0, board);
}

public static void main(String[] args) {
    NQueens nq = new NQueens();
    System.out.println(nq.totalNQueens(2));
}

知道为什么它会因为N的小值而溢出?

2 个答案:

答案 0 :(得分:1)

因为你的方法无限地递归。

如果电路板是8x8,那么例如recurseMark(1, 1, board, false)拨打recurseMark(2, 2, board, false),呼叫recurseMark(1, 1, board, false),呼叫recurseMark(2, 2, board, false),呼叫recurseMark(1, 1, board, false) ......

答案 1 :(得分:1)

问题是当使用false调用recurseMark时。这是一个正确的recurseMark():

private void recurseMark(int row, int col, Boolean[][] board, Boolean val) {
    if(row >= dim || col >= dim || row < 0 || col < 0) return;
    if(board[row][col] != null) return;
    System.out.println("Row " + row + " Col " + col);
    board[row][col] = val;
    recurseMark(row+1, col-1, board, val);
    recurseMark(row+1, col+1, board, val);
    recurseMark(row-1, col+1, board, val);
    recurseMark(row-1, col-1, board, val);
}

我们在这里做的是切换到布尔类而不是原始布尔值,并使用空案例来表示未被访问过的&#34; square&#34;。因为它没有被访问的&#34;广场&#34;国家是&#34;假&#34;。