Cantor展开、全排列问题、魔板问题(JAVA实现)

本文介绍了Cantor展开的概念,提供了全排列问题的递归和非递归JAVA实现,并详细讲解了魔板问题,利用Cantor展开解决状态查找和计数问题。内容涵盖全排列算法、Cantor展开公式及其应用。
摘要由CSDN通过智能技术生成

Cantor展开、全排列问题、魔板问题(JAVA实现)

本文由全排列问题的递归和非递归写法入手,引出Cantor展开的公式及其应用,最后讨论Cantor数的经典应用之魔板问题

  • 全排列问题
  • Cantor展开
  • 魔板问题

目录

问题:给定字符串S[0…N-1],设计算法,枚举S的全排列

以一个简单的示例来表示解题过程
示例 枚举0123的全排列
0123 0132 0213 0231 0312 0321
1023 1032 1203 1230 1302 1320
2013 2031 2103 2130 2301 2310
3012 3021 3102 3120 3201 3210
手动写出这些序列的时候,实际上是脑补了一个树形结构,如下:
这里写图片描述
画出这个树的过程实际上是一个深度搜索的过程,每次到达叶子节点时就产生一个输出,之后再回溯,搜索下一个叶子节点。
深度搜索的过程实际上就是一个入栈出栈的过程,也就是一个递归过程。

全排列之递归解法

使用递归时,代码结构是很清晰,也容易理解,便不再赘述,直接上代码。

//无重复的全排列递归写法
public class Permutation {
    public static final int N = 4;
    public static void main(String[] args){
        //初始化
        int[] sequence = new int[N];
        for(int i = 0;i < N;i++){
            sequence[i] = i+1;
        }
        permutation(sequence,N,0);
    }

    private static void print(int[] sequence){
        for(int i : sequence){
            System.out.print(i);
        }
        System.out.println();
    }

    private static void swap(int[] sequence,int i, int j){
        int tmp = sequence[i];
        sequence[i] = sequence[j];
        sequence[j] = tmp;
    }
    //固定前n位的全排列
    public static void permutation(int[] sequence, int size, int n){
        if(n == size - 1) print(sequence);

        for(int i = n; i < size;i++){
            //用其他位来交换第n位
            swap(sequence,i,n);
            permutation(sequence,size,n+1);
            swap(sequence,i,n);
        }
    }
}

当出现重复元素时,在用其他位交换第n位时,会有相同的两个位均与n位发生了交换。所以我们需要在交换时判断该位是否在之前已经被放置到n位过。
为了判断某个元素是否已经被访问过,另增加一个duplication数组。
与无重复元素的序列全排列相比,仅在permutation函数中增加了一个参数及两行代码。
代码如下

//有重复的递归写法
public class PermutationWithDuplicate {
   
    public static final int N = 4;

    public static void main(String[] args){
        //初始化
        int[] sequence = {
  1,2,3,4};
        boolean[] duplication = new boolean[N];
        permutation(duplication,sequence,N,0);
    }

    private 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值