回溯算法递归学习

在递归调用中,参数传递的方式决定了变量的状态如何在递归调用之间传递和恢复。让我们分别来看一下这两种情况:

  1. solveNQueens(board, col + 1)
    在这种情况下,col + 1 是一个表达式,它计算出一个新的值,并且这个值作为参数传递给递归调用。col 的原始值并没有被修改。

  2. col = col + 1; solveNQueens(board, col);
    在这种情况下,先修改了 col 的值,然后使用修改后的值进行递归调用。由于 col 的值在当前作用域内被修改了,因此需要在递归调用完成后恢复其原始值。
    情况 1: solveNQueens(board, col + 1)

```java
res = solveNQueens(board, col + 1) || res;
这里 col + 1 是一个表达式,它计算出一个新的值,并且这个值作为参数传递给递归调用。当前函数调用中的 col 的值并没有被修改。因此,当递归调用返回时,col 的值仍然是原来的值,不需要恢复。
**情况 2:** col = col + 1; solveNQueens(board, col);

```java
col = col + 1;
res = solveNQueens(board, col) || res;

在这里,col 的值被修改了,这意味着当前函数调用中的 col 的值已经不再是原来的值。因此,当递归调用返回时,我们需要恢复 col 的原始值,否则会导致后续的逻辑错误。
示例对比
使用 solveNQueens(board, col + 1)

public static boolean solveNQueens(int[][] board, int col) {
    if (col >= board.length) {
        // 所有皇后都已经放置好了
        printBoard(board);
        return true;
    }

    boolean res = false;
    for (int i = 0; i < board.length; i++) {
        if (isSafe(board, i, col)) {
            board[i][col] = 1; // 放置皇后
            res = solveNQueens(board, col + 1) || res; // 递归调用
            board[i][col] = 0; // 回溯,移除皇后
        }
    }
    return res;
}

在这个版本中,col 的值在每次递归调用中都是一个新的值,当前函数调用中的 col 值没有被修改。
使用 col = col + 1; solveNQueens(board, col);

public static boolean solveNQueens(int[][] board, int col) {
    if (col >= board.length) {
        // 所有皇后都已经放置好了
        printBoard(board);
        return true;
    }

    boolean res = false;
    for (int i = 0; i < board.length; i++) {
        if (isSafe(board, i, col)) {
            board[i][col] = 1; // 放置皇后
            col = col + 1; // 修改 col 的值
            res = solveNQueens(board, col) || res; // 递归调用
            board[i][col] = 0; // 回溯,移除皇后
            col = col - 1; // 恢复 col 的值
        }
    }
    return res;
}

在这个版本中,col 的值在每次递归调用之前被修改了,因此需要在递归调用之后恢复其原始值。
总结
不修改 col 的值 (solveNQueens(board, col + 1)):
递归调用中传递的是 col 的新值。
当前函数调用中的 col 值保持不变。
不需要显式恢复 col 的值。
修改 col 的值 (col = col + 1; solveNQueens(board, col)😉:
在当前函数调用中修改了 col 的值。
需要在递归调用之后恢复 col 的值,以确保后续逻辑正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值