java递归解决全排列的邻位交换法

public class Permutation {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        permute(arr, 0, arr.length - 1);
    }

    public static void permute(int[] arr, int left, int right) {
        if (left == right) {
            printArray(arr);
        } else {
            for (int i = left; i <= right; i++) {
                swap(arr, left, i);
                permute(arr, left + 1, right);
                swap(arr, left, i); // 恢复数组状态,进行下一次交换
            }
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

解释一下原理

在上述代码中,permute 方法是递归函数,它接收一个数组 arr,以及左边界 left 和右边界 right。初始调用时,left 设为 0,right 设为数组长度减 1。

递归过程中,首先判断 left 是否等于 right,如果相等,则表示已经完成了一种排列,将数组打印出来。

如果 left 不等于 right,则进行循环遍历,将 arr[left] 与从 left 到 right 的每个元素进行交换,并递归调用 permute 函数。

在每次递归调用后,需要恢复数组的状态,以便进行下一次交换。

例如设数组arr为{1,2,3}也就是对123进行全排列

假设输入数组为 [1, 2, 3],初始调用 permute(arr, 0, arr.length - 1)

  1. 第一次递归调用:

    • left = 0right = 2,不满足 left == right,进入循环。
    • i = 0,进行交换 swap(arr, 0, 0),数组变为 [1, 2, 3]
    • 递归调用 permute(arr, 1, 2)
  2. 第二次递归调用:

    • left = 1right = 2,不满足 left == right,进入循环。
    • i = 1,进行交换 swap(arr, 1, 1),数组仍然是 [1, 2, 3]
    • 递归调用 permute(arr, 2, 2)
  3. 第三次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [1, 2, 3]
  4. 返回到第二次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),数组变为 [1, 3, 2]
    • 递归调用 permute(arr, 2, 2)
  5. 第四次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [1, 3, 2]
  6. 返回到第二次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),恢复数组为 [1, 2, 3]
    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),数组仍然是 [1, 2, 3]
  7. 返回到第一次递归调用:

    • 继续循环,i = 1,进行交换 swap(arr, 0, 1),数组变为 [2, 1, 3]
    • 递归调用 permute(arr, 1, 2)
  8. 第五次递归调用:

    • left = 1right = 2,不满足 left == right,进入循环。
    • i = 1,进行交换 swap(arr, 1, 1),数组仍然是 [2, 1, 3]
    • 递归调用 permute(arr, 2, 2)
  9. 第六次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [2, 1, 3]
  10. 返回到第五次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),数组变为 [2, 3, 1]
    • 递归调用 permute(arr, 2, 2)
  11. 第七次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [2, 3, 1]
  12. 返回到第五次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),恢复数组为 [2, 1, 3]
  13. 返回到第一次递归调用:
    - 继续循环,i = 2,进行交换 swap(arr, 0, 2),数组变为 [3, 2, 1]
    - 递归调用 permute(arr, 1, 2)

  14. 第八次递归调用:

    • left = 1right = 2,不满足 left == right,进入循环。
    • i = 1,进行交换 swap(arr, 1, 1),数组仍然是 [3, 2, 1]
    • 递归调用 permute(arr, 2, 2)
  15. 第九次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [3, 2, 1]
  16. 返回到第八次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),数组变为 [3, 1, 2]
    • 递归调用 permute(arr, 2, 2)
  17. 第十次递归调用:

    • left = 2right = 2,满足 left == right,执行打印操作 printArray(arr),输出 [3, 1, 2]
  18. 返回到第八次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 1, 2),恢复数组为 [3, 2, 1]
  19. 返回到第一次递归调用:

    • 继续循环,i = 2,进行交换 swap(arr, 0, 2),恢复数组为 [1, 2, 3]

最终,该递归算法会生成并打印出数组 [1, 2, 3] 的所有全排列。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值